@stacksjs/actions 0.72.5 → 0.72.7

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/action.d.ts CHANGED
@@ -33,7 +33,7 @@ export declare interface ActionResponse {
33
33
  description: string
34
34
  schema?: Record<string, unknown>
35
35
  }
36
- declare interface ActionOptions<TModel = string, TValidations extends ActionValidations | undefined = undefined, TPath extends string = '',> {
36
+ declare interface ActionOptions<TModel = string, TValidations extends ActionValidations | undefined = undefined, TPath extends string = '', /** * The payload `handle` receives when the action is invoked by something * other than the router - an event listener, for instance, which calls it * with the event object rather than a request (`app/Events.ts` maps * 'user:registered' straight onto an action name). Defaults to `never`, * which leaves every HTTP action typed exactly as before. */ TPayload = never,> {
37
37
  name?: string
38
38
  description?: string
39
39
  apiResponse?: boolean
@@ -58,7 +58,7 @@ declare interface ActionOptions<TModel = string, TValidations extends ActionVali
58
58
  ) => void | Response | Promise<void | Response>
59
59
  handle: {
60
60
  bivarianceHack: (
61
- request: InferRequest<TModel, TValidations, TPath>,
61
+ request: [TPayload] extends [never] ? InferRequest<TModel, TValidations, TPath> : TPayload,
62
62
  ) => ActionResult | Promise<ActionResult>
63
63
  }['bivarianceHack']
64
64
  dependencies?: () => Record<string, unknown>
@@ -114,7 +114,7 @@ export type ActionResult = | Response
114
114
  | boolean
115
115
  | object
116
116
  | unknown[];
117
- export declare class Action<TModel = string, TValidations extends ActionValidations | undefined = undefined, TPath extends string = '',> {
117
+ export declare class Action<TModel = string, TValidations extends ActionValidations | undefined = undefined, TPath extends string = '', TPayload = never,> {
118
118
  name?: string;
119
119
  description?: string;
120
120
  apiResponse?: boolean;
@@ -132,7 +132,7 @@ export declare class Action<TModel = string, TValidations extends ActionValidati
132
132
  csrf?: boolean;
133
133
  authorize?: ActionOptions<TModel, TValidations, TPath>['authorize'];
134
134
  before?: ActionOptions<TModel, TValidations, TPath>['before'];
135
- handle: ActionOptions<TModel, TValidations, TPath>['handle'];
135
+ handle: ActionOptions<TModel, TValidations, TPath, TPayload>['handle'];
136
136
  model?: string;
137
137
  modelDefinition?: TModel;
138
138
  constructor({
@@ -156,7 +156,7 @@ export declare class Action<TModel = string, TValidations extends ActionValidati
156
156
  authorize,
157
157
  before,
158
158
  dependencies,
159
- }: ActionOptions<TModel, TValidations, TPath>);
159
+ }: ActionOptions<TModel, TValidations, TPath, TPayload>);
160
160
  get deps(): Record<string, unknown>;
161
161
  overrideDependencies(overrides: Record<string, unknown>): void;
162
162
  resetDependencies(): void;
@@ -1,3 +1,4 @@
1
+ import type { ResponseStatus } from '@stacksjs/bun-router';
1
2
  /**
2
3
  * Turn a title into a filename-safe slug.
3
4
  *
@@ -50,6 +51,6 @@ export declare interface BlogPostInput {
50
51
  body?: string
51
52
  }
52
53
  export declare class BlogAdminError extends Error {
53
- readonly status?: number;
54
- constructor(message: string, status?: number);
54
+ readonly status?: ResponseStatus;
55
+ constructor(message: string, status?: ResponseStatus);
55
56
  }
package/dist/make.d.ts CHANGED
@@ -12,7 +12,12 @@ export declare function make(options: MakeOptions): Promise<void>;
12
12
  export declare function makeAction(options: MakeOptions): Promise<void>;
13
13
  export declare function makeComponent(options: MakeOptions): Promise<void>;
14
14
  export declare function createAction(options: MakeOptions): Promise<void>;
15
- export declare function createComponent(options: MakeOptions): Promise<void>;
15
+ /**
16
+ * Only `name` is read here, so only `name` is required. Taking the full
17
+ * `MakeOptions` - whose members are all mandatory - meant a caller with just a
18
+ * name (the dashboard's "new component" button) could not call this at all.
19
+ */
20
+ export declare function createComponent(options: Pick<MakeOptions, 'name'>): Promise<void>;
16
21
  export declare function componentFileName(name: string): string;
17
22
  export declare function makeDatabase(options: MakeOptions): void;
18
23
  export declare function createDatabase(options: MakeOptions): void;
@@ -42,7 +47,8 @@ export declare function makePage(options: MakeOptions): Promise<void>;
42
47
  export declare function createPage(options: MakeOptions): Promise<void>;
43
48
  export declare function pageFileName(name: string): string;
44
49
  export declare function makeFunction(options: MakeOptions): Promise<void>;
45
- export declare function createFunction(options: MakeOptions): Promise<void>;
50
+ /** As `createComponent`: the name is the only option this reads. */
51
+ export declare function createFunction(options: Pick<MakeOptions, 'name'>): Promise<void>;
46
52
  export declare function makeLanguage(options: MakeOptions): Promise<void>;
47
53
  export declare function createLanguage(options: MakeOptions): Promise<void>;
48
54
  export declare function makeStack(options: MakeOptions): Promise<void>;
package/dist/release.js CHANGED
@@ -1 +1 @@
1
- import{parseOptions}from"@stacksjs/cli";import{app}from"@stacksjs/config";import{Action}from"@stacksjs/enums";import{log}from"@stacksjs/logging";import{projectPath}from"@stacksjs/path";import{runActions}from".";import{BYPASS_ENV,formatPreflightFailure,runPinnedChecks}from"./release-preflight";const raw=parseOptions()??{},passthrough={};for(const[k,v]of Object.entries(raw)){if(k==="--"||k==="_")continue;passthrough[k]=v}const isDryRun=passthrough.dryRun===!0||passthrough.dryRun==="true",actions=isDryRun?[Action.GenerateLibraryEntries,Action.Bump]:[Action.GenerateLibraryEntries,Action.LintFix,Action.Bump],preflight=await runPinnedChecks({cwd:projectPath()});if(preflight.bypassed)log.warn(`${BYPASS_ENV} is set, so the pinned checks were skipped for this release.`);else if(preflight.failures.length>0)await log.exit(formatPreflightFailure(preflight.failures),1);const result=await runActions(actions,{cwd:projectPath(),...passthrough});if(result&&result.isErr)await log.exit(`Release failed: ${result.error?.message??String(result.error)}`,1);log.success(`Successfully released ${app.name}`);
1
+ import{parseOptions}from"@stacksjs/cli";import{app}from"@stacksjs/config";import{Action}from"@stacksjs/enums";import{log}from"@stacksjs/logging";import{projectPath}from"@stacksjs/path";import{runActions}from".";import{BYPASS_ENV,formatPreflightFailure,runPinnedChecks}from"./release-preflight";const raw=parseOptions()??{},passthrough={};for(const[k,v]of Object.entries(raw)){if(k==="--"||k==="_")continue;passthrough[k]=v}const isDryRun=passthrough.dryRun===!0||passthrough.dryRun==="true",actions=isDryRun?[Action.GenerateLibraryEntries,Action.Bump]:[Action.GenerateLibraryEntries,Action.LintFix,Action.Bump],preflight=await runPinnedChecks({cwd:projectPath()});if(preflight.bypassed)log.warn(`${BYPASS_ENV} is set, so the pinned checks were skipped for this release.`);else if(preflight.failures.length>0)await log.exit(formatPreflightFailure(preflight.failures),1);const result=await runActions(actions,{cwd:projectPath(),...passthrough});if(result&&result.isErr)await log.exit(`Release failed: ${result.error?.message??String(result.error)}`,1);log.success(isDryRun?`Dry run complete for ${app.name}. Nothing was committed, tagged or pushed.`:`Successfully released ${app.name}`);
@@ -23,13 +23,15 @@ export declare function applyBumps(pkg: PkgJson, target: string, lockstep: Set<s
23
23
  * Handles resolution, package.json rewrite, and reinstall; then `process.exit`s.
24
24
  */
25
25
  export declare function upgradeStacksPackages(projectRoot: string, options: PackageUpgradeOptions): Promise<never>;
26
- /**` pointed at them by workspace
27
- * reference. Delete that directory to move onto published packages and those
28
- * references resolve to nothing: `bun install` fails outright with
29
- * "@stacksjs/utils@workspace:* failed to resolve", and the app cannot install
30
- * at all until every one of them is rewritten by hand.
26
+ /*` package rides the framework version, though, and the
27
+ * doc above used to describe a guard the code did not have: without `context`
28
+ * this rewrote `@stacksjs/bun-router: ^0.0.20` to `^0.72.4`, a version that
29
+ * package has never published, so the "upgrade" left the app unable to install
30
+ * - the same trap #2078 fixed for the root manifest. Pass `context` and an
31
+ * independently-versioned package takes the meta's declared range instead, or
32
+ * is reported rather than guessed at.
31
33
  */
32
- export declare function resolveManifestSpec(name: string, spec: string, target: string): string | null;
34
+ export declare function resolveManifestSpec(name: string, spec: string, target: string, context?: ManifestSpecContext): string | null;
33
35
  /*` dependencies, and an upgrade that ignores them leaves the app
34
36
  * describing two different framework versions at once - or, after a vendored
35
37
  * core is removed, unable to install.
@@ -37,7 +39,7 @@ export declare function resolveManifestSpec(name: string, spec: string, target:
37
39
  * Returns what changed so the caller can report it. Writes nothing when
38
40
  * `dryRun` is set.
39
41
  */
40
- export declare function reconcileVendoredManifests(projectRoot: string, target: string, options?: { dryRun?: boolean }): ManifestChange[];
42
+ export declare function reconcileVendoredManifests(projectRoot: string, target: string, options?: { dryRun?: boolean, context?: ManifestSpecContext }): ManifestChange[];
41
43
  export declare interface PackageUpgradeOptions {
42
44
  version?: string
43
45
  canary?: boolean
@@ -58,3 +60,8 @@ export declare interface ManifestChange {
58
60
  from: string
59
61
  to: string
60
62
  }
63
+ /** What the framework knows about the target release, for spec decisions. */
64
+ export declare interface ManifestSpecContext {
65
+ lockstep: Set<string>
66
+ metaDeps: Record<string, string>
67
+ }
@@ -4,7 +4,7 @@ import{existsSync,readdirSync,readFileSync,statSync,writeFileSync}from"node:fs";
4
4
  \u2714 Standalone package dependencies are up to date.
5
5
  `);process.exit(0)}async function resolveTarget(options){const res=await fetch("https://registry.npmjs.org/stacks").catch(()=>null);if(!res||!res.ok)throw Error("Could not reach the npm registry to resolve the target `stacks` version.");const meta=await res.json(),distTags=meta["dist-tags"]??{},versions=meta.versions??{};let version;if(options.version){if(!versions[options.version])throw Error(`stacks@${options.version} was not found on the npm registry.`);version=options.version}else{const tag=options.canary?"canary":"latest",resolved=distTags[tag];if(!resolved)throw Error(`The \`${tag}\` dist-tag is not published for \`stacks\`.`);version=resolved}const metaDeps=versions[version]?.dependencies??{};return{version,metaDeps}}export function baseVersion(range){return range.replace(/^[\^~>=<\s]+/,"").trim()}export function lockstepPackages(metaDeps,target){const lockstep=new Set(["stacks"]);for(const[name,range]of Object.entries(metaDeps))if(name.startsWith("@stacksjs/")&&baseVersion(range)===target)lockstep.add(name);return lockstep}export function applyBumps(pkg,target,lockstep){const changes=[];for(const field of["dependencies","devDependencies"]){const deps=pkg[field];if(!deps)continue;for(const[name,spec]of Object.entries(deps)){if(!lockstep.has(name))continue;const next=`${/^[\^~]/.test(spec)?spec[0]:/^\d/.test(spec)?"":"^"}${target}`;if(spec!==next){changes.push({name,from:spec,to:next});deps[name]=next}}}return changes}export async function upgradeStacksPackages(projectRoot,options){const pkgPath=join(projectRoot,"package.json");if(!existsSync(pkgPath)){console.error("No package.json found \u2014 nothing to upgrade.");process.exit(1)}const raw=readFileSync(pkgPath,"utf-8"),pkg=JSON.parse(raw),current=pkg.dependencies?.stacks??pkg.devDependencies?.stacks;if(!hasStacksDependency(pkg))return updateStandalonePackage(projectRoot,options);const{version:target,metaDeps}=await resolveTarget(options).catch((err)=>{console.error(`\u2717 ${err.message}`);process.exit(1)});console.log(`
6
6
  Upgrading the Stacks framework${options.canary?" (canary)":""} \u2192 ${target}`);if(current)console.log(` current \`stacks\` constraint: ${current}
7
- `);const lockstep=lockstepPackages(metaDeps,target),changes=applyBumps(pkg,target,lockstep),projectManifestChanges=migratePackageProjectManifest(pkg),manifestChanges=reconcileVendoredManifests(projectRoot,target,{dryRun:options.dryRun});if(changes.length>0){console.log(" The following dependencies will be updated:");const width=Math.max(...changes.map((c)=>c.name.length));for(const c of changes)console.log(` ${c.name.padEnd(width)} ${c.from} \u2192 ${c.to}`);console.log("")}if(manifestChanges.length>0){console.log(` Vendored manifests under storage/framework (${manifestChanges.length}):`);const width=Math.max(...manifestChanges.map((c)=>c.name.length));for(const c of manifestChanges)console.log(` ${c.name.padEnd(width)} ${c.from} \u2192 ${c.to} ${c.file}`);console.log("")}if(projectManifestChanges.length>0)console.log(` Project manifest migrations: ${projectManifestChanges.length}
7
+ `);const lockstep=lockstepPackages(metaDeps,target),changes=applyBumps(pkg,target,lockstep),projectManifestChanges=migratePackageProjectManifest(pkg),manifestChanges=reconcileVendoredManifests(projectRoot,target,{dryRun:options.dryRun,context:{lockstep,metaDeps}});if(changes.length>0){console.log(" The following dependencies will be updated:");const width=Math.max(...changes.map((c)=>c.name.length));for(const c of changes)console.log(` ${c.name.padEnd(width)} ${c.from} \u2192 ${c.to}`);console.log("")}if(manifestChanges.length>0){console.log(` Vendored manifests under storage/framework (${manifestChanges.length}):`);const width=Math.max(...manifestChanges.map((c)=>c.name.length));for(const c of manifestChanges)console.log(` ${c.name.padEnd(width)} ${c.from} \u2192 ${c.to} ${c.file}`);console.log("")}if(projectManifestChanges.length>0)console.log(` Project manifest migrations: ${projectManifestChanges.length}
8
8
  `);if(options.dryRun){const pending=measureDefaultsDrift(projectRoot);if(pending&&pending.length>0){const installed=installedDefaultsVersion(projectRoot);console.log(` Managed project files, against the installed @stacksjs/defaults${installed?` (${installed})`:""}:`);console.log(` ${summarizeStructureChanges(pending)} in storage/framework/defaults and project support files
9
9
  `)}console.log(` --dry-run: no files were written and nothing was installed.
10
10
  `);process.exit(0)}if(changes.length>0||projectManifestChanges.length>0){const trailing=raw.endsWith(`
@@ -17,6 +17,6 @@ import{existsSync,readdirSync,readFileSync,statSync,writeFileSync}from"node:fs";
17
17
  \u2714 Already up to date \u2014 dependencies and managed project files match the target.
18
18
  `);else console.log(`
19
19
  \u2714 Upgraded to stacks@${target}. Review the changelog: https://github.com/stacksjs/stacks/releases/tag/v${target}
20
- `);process.exit(0)}export function resolveManifestSpec(name,spec,target){if(name!=="stacks"&&!name.startsWith("@stacksjs/"))return null;if(spec.startsWith("workspace:"))return`^${target}`;if(baseVersion(spec)===target)return null;if(!/^[\^~]?\d/.test(spec))return null;return`${/^[\^~]/.test(spec)?spec[0]:""}${target}`}export function reconcileVendoredManifests(projectRoot,target,options={}){const root=join(projectRoot,"storage/framework");if(!existsSync(root))return[];const changes=[],walk=(dir)=>{let entries;try{entries=readdirSync(dir)}catch{return}for(const entry of entries){if(entry==="node_modules"||entry==="dist"||entry===".git")continue;const full=join(dir,entry);let stat;try{stat=statSync(full)}catch{continue}if(stat.isDirectory()){walk(full);continue}if(entry!=="package.json")continue;let raw;try{raw=readFileSync(full,"utf-8")}catch{continue}let pkg;try{pkg=JSON.parse(raw)}catch{continue}let touched=!1;for(const field of["dependencies","devDependencies"]){const deps=pkg[field];if(!deps)continue;for(const[name,spec]of Object.entries(deps)){const next=resolveManifestSpec(name,spec,target);if(!next)continue;changes.push({file:relative(projectRoot,full),name,from:spec,to:next});deps[name]=next;touched=!0}}if(touched&&!options.dryRun){const suffix=raw.endsWith(`
20
+ `);process.exit(0)}export function resolveManifestSpec(name,spec,target,context){if(name!=="stacks"&&!name.startsWith("@stacksjs/"))return null;if(context&&!context.lockstep.has(name)){const declared=context.metaDeps[name];if(!declared)return null;return baseVersion(declared)===baseVersion(spec)?null:declared}if(spec.startsWith("workspace:"))return`^${target}`;if(baseVersion(spec)===target)return null;if(!/^[\^~]?\d/.test(spec))return null;return`${/^[\^~]/.test(spec)?spec[0]:""}${target}`}export function reconcileVendoredManifests(projectRoot,target,options={}){const root=join(projectRoot,"storage/framework");if(!existsSync(root))return[];const changes=[],walk=(dir)=>{let entries;try{entries=readdirSync(dir)}catch{return}for(const entry of entries){if(entry==="node_modules"||entry==="dist"||entry===".git")continue;const full=join(dir,entry);let stat;try{stat=statSync(full)}catch{continue}if(stat.isDirectory()){walk(full);continue}if(entry!=="package.json")continue;let raw;try{raw=readFileSync(full,"utf-8")}catch{continue}let pkg;try{pkg=JSON.parse(raw)}catch{continue}let touched=!1;for(const field of["dependencies","devDependencies"]){const deps=pkg[field];if(!deps)continue;for(const[name,spec]of Object.entries(deps)){const next=resolveManifestSpec(name,spec,target,options.context);if(!next)continue;changes.push({file:relative(projectRoot,full),name,from:spec,to:next});deps[name]=next;touched=!0}}if(touched&&!options.dryRun){const suffix=raw.endsWith(`
21
21
  `)?`
22
22
  `:"";writeFileSync(full,`${JSON.stringify(pkg,null,2)}${suffix}`)}}};walk(root);return changes}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/actions",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.72.5",
5
+ "version": "0.72.7",
6
6
  "description": "The Stacks actions.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -59,36 +59,36 @@
59
59
  "prepublishOnly": "bun run build"
60
60
  },
61
61
  "dependencies": {
62
- "@stacksjs/config": "0.72.5",
62
+ "@stacksjs/config": "0.72.7",
63
63
  "@stacksjs/bumpx": "^0.2.6",
64
64
  "@stacksjs/bunpress": "^0.2.6",
65
65
  "@stacksjs/logsmith": "^0.2.3",
66
- "@stacksjs/registry": "0.72.5",
66
+ "@stacksjs/registry": "0.72.7",
67
67
  "@stacksjs/stx": "^0.2.184",
68
68
  "@stacksjs/ts-cloud": "^0.8.3",
69
69
  "@stacksjs/ts-md": "^0.1.1",
70
70
  "craft-native": ">=0.0.55"
71
71
  },
72
72
  "devDependencies": {
73
- "@stacksjs/api": "0.72.5",
74
- "@stacksjs/cli": "0.72.5",
75
- "@stacksjs/database": "0.72.5",
73
+ "@stacksjs/api": "0.72.7",
74
+ "@stacksjs/cli": "0.72.7",
75
+ "@stacksjs/database": "0.72.7",
76
76
  "@stacksjs/tlsx": "^0.13.2",
77
77
  "better-dx": "^0.2.23",
78
- "@stacksjs/dns": "0.72.5",
79
- "@stacksjs/enums": "0.72.5",
80
- "@stacksjs/env": "0.72.5",
81
- "@stacksjs/error-handling": "0.72.5",
82
- "@stacksjs/image": "0.72.5",
83
- "@stacksjs/logging": "0.72.5",
84
- "@stacksjs/path": "0.72.5",
85
- "@stacksjs/security": "0.72.5",
86
- "@stacksjs/cms": "0.72.5",
87
- "@stacksjs/sites": "0.72.5",
88
- "@stacksjs/storage": "0.72.5",
89
- "@stacksjs/strings": "0.72.5",
90
- "@stacksjs/utils": "0.72.5",
91
- "@stacksjs/validation": "0.72.5"
78
+ "@stacksjs/dns": "0.72.7",
79
+ "@stacksjs/enums": "0.72.7",
80
+ "@stacksjs/env": "0.72.7",
81
+ "@stacksjs/error-handling": "0.72.7",
82
+ "@stacksjs/image": "0.72.7",
83
+ "@stacksjs/logging": "0.72.7",
84
+ "@stacksjs/path": "0.72.7",
85
+ "@stacksjs/security": "0.72.7",
86
+ "@stacksjs/cms": "0.72.7",
87
+ "@stacksjs/sites": "0.72.7",
88
+ "@stacksjs/storage": "0.72.7",
89
+ "@stacksjs/strings": "0.72.7",
90
+ "@stacksjs/utils": "0.72.7",
91
+ "@stacksjs/validation": "0.72.7"
92
92
  },
93
93
  "peerDependencies": {
94
94
  "pickier": "^0.1.35"