auklet 0.0.19 → 0.0.21

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 (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +183 -393
  3. package/bin/entry.mjs +5 -0
  4. package/dist/build/bundleConfig.js +3 -2
  5. package/dist/build/cliOverrides.d.ts +22 -0
  6. package/dist/build/cliOverrides.js +22 -0
  7. package/dist/build/moduleConfig.js +1 -1
  8. package/dist/build/runTsdown.d.ts +2 -0
  9. package/dist/build/runTsdown.js +4 -3
  10. package/dist/build/tsdown/common.d.ts +2 -2
  11. package/dist/build/tsdown/context.d.ts +2 -1
  12. package/dist/build/tsdown/context.js +2 -1
  13. package/dist/build/tsdown/define.js +3 -2
  14. package/dist/build/tsdown/dependencies.js +3 -1
  15. package/dist/build/tsdown/entries.d.ts +2 -2
  16. package/dist/build/tsdown/entries.js +10 -10
  17. package/dist/build/tsdown/types.d.ts +1 -0
  18. package/dist/cli/build.d.ts +5 -0
  19. package/dist/cli/build.js +30 -0
  20. package/dist/cli/buildArgs.d.ts +8 -0
  21. package/dist/cli/buildArgs.js +114 -0
  22. package/dist/cli/buildCss.d.ts +12 -0
  23. package/dist/cli/buildCss.js +53 -0
  24. package/dist/cli/dev.d.ts +1 -0
  25. package/dist/cli/dev.js +39 -0
  26. package/dist/cli/main.d.ts +1 -0
  27. package/dist/cli/main.js +95 -0
  28. package/dist/cli/publish.d.ts +2 -0
  29. package/dist/cli/publish.js +9 -0
  30. package/dist/config.d.ts +3 -1
  31. package/dist/config.js +7 -1
  32. package/dist/configLoader.d.ts +1 -0
  33. package/dist/configLoader.js +42 -61
  34. package/dist/css/production/buildReporter.d.ts +3 -0
  35. package/dist/css/production/buildReporter.js +19 -0
  36. package/dist/css/production/builder.d.ts +8 -3
  37. package/dist/css/production/builder.js +9 -13
  38. package/dist/css/vite/hmr.js +10 -8
  39. package/dist/css/vite/moduleGraph/graph.js +2 -3
  40. package/dist/css/vite/moduleGraph/packageSource/monorepo.d.ts +5 -1
  41. package/dist/css/vite/moduleGraph/packageSource/monorepo.js +42 -33
  42. package/dist/css/vite/moduleGraph/packageSource/singlePackage.js +3 -3
  43. package/dist/css/vite/moduleGraph/requestCache.d.ts +4 -4
  44. package/dist/css/vite/moduleGraph/requestCache.js +8 -4
  45. package/dist/css/vite/moduleGraph/styleCodeFactory.js +4 -4
  46. package/dist/css/vite/moduleGraph/types.d.ts +0 -1
  47. package/dist/css/watch/watcher.d.ts +0 -1
  48. package/dist/css/watch/watcher.js +9 -15
  49. package/dist/index.d.ts +6 -7
  50. package/dist/index.js +5 -5
  51. package/dist/logger.d.ts +5 -0
  52. package/dist/logger.js +14 -0
  53. package/dist/publish/api/gitApi.d.ts +7 -0
  54. package/dist/publish/api/gitApi.js +55 -0
  55. package/dist/publish/api/packageJsonApi.d.ts +7 -0
  56. package/dist/publish/api/packageJsonApi.js +35 -0
  57. package/dist/publish/api/pnpmApi.d.ts +9 -0
  58. package/dist/publish/api/pnpmApi.js +85 -0
  59. package/dist/publish/api/pnpmPublishApi.d.ts +4 -0
  60. package/dist/publish/api/pnpmPublishApi.js +7 -0
  61. package/dist/publish/api/publishArgs.d.ts +2 -0
  62. package/dist/publish/api/publishArgs.js +25 -0
  63. package/dist/publish/api/publishHookApi.d.ts +10 -0
  64. package/dist/publish/api/publishHookApi.js +53 -0
  65. package/dist/publish/cli.d.ts +2 -0
  66. package/dist/publish/cli.js +95 -0
  67. package/dist/publish/ownerRunner.d.ts +6 -0
  68. package/dist/publish/ownerRunner.js +22 -0
  69. package/dist/publish/publishRunner.d.ts +16 -0
  70. package/dist/publish/publishRunner.js +108 -0
  71. package/dist/publish/runner/packageBuilder.d.ts +4 -0
  72. package/dist/publish/runner/packageBuilder.js +16 -0
  73. package/dist/publish/runner/packagePublisher.d.ts +7 -0
  74. package/dist/publish/runner/packagePublisher.js +21 -0
  75. package/dist/publish/runner/publishFailureReporter.d.ts +3 -0
  76. package/dist/publish/runner/publishFailureReporter.js +14 -0
  77. package/dist/publish/runner/publishOutputFormatter.d.ts +2 -0
  78. package/dist/publish/runner/publishOutputFormatter.js +83 -0
  79. package/dist/publish/runner/publishPreflight.d.ts +8 -0
  80. package/dist/publish/runner/publishPreflight.js +26 -0
  81. package/dist/publish/runner/publishSummaryReporter.d.ts +10 -0
  82. package/dist/publish/runner/publishSummaryReporter.js +81 -0
  83. package/dist/publish/runner/publishTargetError.d.ts +9 -0
  84. package/dist/publish/runner/publishTargetError.js +14 -0
  85. package/dist/publish/runner/releaseGitController.d.ts +10 -0
  86. package/dist/publish/runner/releaseGitController.js +41 -0
  87. package/dist/publish/runner/versionWriter.d.ts +13 -0
  88. package/dist/publish/runner/versionWriter.js +78 -0
  89. package/dist/publish/targetResolver.d.ts +7 -0
  90. package/dist/publish/targetResolver.js +195 -0
  91. package/dist/publish/types.d.ts +70 -0
  92. package/dist/publish/types.js +0 -0
  93. package/dist/publish/version.d.ts +5 -0
  94. package/dist/publish/version.js +55 -0
  95. package/dist/types.d.ts +8 -7
  96. package/dist/workspace/packages.d.ts +9 -0
  97. package/dist/workspace/packages.js +62 -0
  98. package/dist/workspace/root.d.ts +1 -0
  99. package/dist/workspace/root.js +14 -0
  100. package/package.json +15 -7
  101. package/bin/entry.cjs +0 -163
@@ -1,14 +1,14 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import chokidar from 'chokidar';
4
- import { aukletConfigFile, aukletDefaultOptions } from '#auklet/config';
4
+ import { isString } from 'aidly';
5
+ import { aukletConfigFiles, aukletDefaultOptions, isAukletConfigFile, } from '#auklet/config';
5
6
  import { moduleStyleBuildConfig } from '#auklet/css/config';
6
7
  import { SOURCE_MODULE_RE } from '#auklet/css/constants';
7
8
  import { ModuleStyleBuilder } from '#auklet/css/production/builder';
8
9
  export class ModuleStyleWatcher {
9
10
  config;
10
11
  context;
11
- logger;
12
12
  timer = null;
13
13
  isBuilding = false;
14
14
  shouldRebuild = false;
@@ -19,11 +19,9 @@ export class ModuleStyleWatcher {
19
19
  packageRoot: process.cwd(),
20
20
  ...context,
21
21
  };
22
- this.logger = context.logger;
23
22
  }
24
23
  async watch() {
25
24
  await this.rebuild();
26
- this.logger?.log?.('[auklet:css] watch mode ready');
27
25
  }
28
26
  async rebuild() {
29
27
  if (this.isBuilding) {
@@ -37,7 +35,7 @@ export class ModuleStyleWatcher {
37
35
  await this.refreshWatcher();
38
36
  }
39
37
  catch (error) {
40
- this.logger?.error?.(error);
38
+ // Watch mode keeps running after transient build or watcher errors.
41
39
  }
42
40
  finally {
43
41
  this.isBuilding = false;
@@ -51,8 +49,8 @@ export class ModuleStyleWatcher {
51
49
  const aukletConfig = this.context.aukletConfig ?? {};
52
50
  const sourceDir = this.context.source ?? aukletConfig.source ?? aukletDefaultOptions.source;
53
51
  const sourceRoot = path.join(this.context.packageRoot, sourceDir);
54
- const configPath = path.join(this.context.packageRoot, aukletConfigFile);
55
- const watchPaths = [sourceRoot, configPath].filter((file) => fs.existsSync(file));
52
+ const configPaths = aukletConfigFiles.map((file) => path.join(this.context.packageRoot, file));
53
+ const watchPaths = [sourceRoot, ...configPaths].filter((file) => fs.existsSync(file));
56
54
  await this.watcher?.close();
57
55
  this.watcher = chokidar.watch(watchPaths, {
58
56
  ignoreInitial: true,
@@ -60,27 +58,23 @@ export class ModuleStyleWatcher {
60
58
  usePolling: true,
61
59
  });
62
60
  this.watcher.on('all', (_event, file) => {
63
- if (typeof file === 'string' && !this.shouldRebuildForFile(file)) {
61
+ if (isString(file) && !this.shouldRebuildForFile(file)) {
64
62
  return;
65
63
  }
66
64
  this.scheduleBuild();
67
65
  });
68
- this.watcher.on('error', (error) => {
69
- this.logger?.error?.(error);
70
- });
66
+ this.watcher.on('error', () => undefined);
71
67
  }
72
68
  scheduleBuild() {
73
69
  if (this.timer)
74
70
  clearTimeout(this.timer);
75
71
  this.timer = setTimeout(() => {
76
72
  this.timer = null;
77
- this.rebuild().catch((error) => {
78
- this.logger?.error?.(error);
79
- });
73
+ void this.rebuild();
80
74
  }, 80);
81
75
  }
82
76
  shouldRebuildForFile(file) {
83
- if (path.basename(file) === aukletConfigFile)
77
+ if (isAukletConfigFile(path.basename(file)))
84
78
  return true;
85
79
  if (SOURCE_MODULE_RE.test(file))
86
80
  return true;
package/dist/index.d.ts CHANGED
@@ -1,9 +1,8 @@
1
- export type { AukletConfig, ConfigureTsdown, ConfigureTsdownContext, LoadAukletConfigOptions, ModuleStyleBuildConfig, ModuleStyleBuildContext, ModuleStyleBuildOptions, NormalizedAukletConfig, NormalizedStyleDependencyGroup, PackageBuildFormat, PackageBuildOptions, ResolvedModuleStyleBuildContext, StyleDependencyGroup, StyleOptions, } from '#auklet/types';
2
- export type { RunTsdownOptions } from '#auklet/build/runTsdown';
1
+ export type { AukletConfig, ConfigureTsdown, ConfigureTsdownContext, PackageBuildFormat, PackageBuildPlatform, PackageBuildOptions, PackageBuildTarget, StyleDependencyGroup, StyleOptions, } from '#auklet/types';
3
2
  export type { AukletStylePluginOptions } from '#auklet/css/vite/vitePlugin';
4
- export { aukletDefaultOptions, aukletDefaultStyleDependencyConfig, normalizeAukletConfig, } from '#auklet/config';
5
- export { loadAukletConfig, resolveAukletConfigModule, } from '#auklet/configLoader';
3
+ export { runAukletCli } from '#auklet/cli/main';
4
+ export { runTsdown } from '#auklet/build/runTsdown';
5
+ export { loadAukletConfig } from '#auklet/configLoader';
6
+ export { defineConfig } from '#auklet/config';
6
7
  export { aukletStylePlugin } from '#auklet/css/vite/vitePlugin';
7
- export { createTsdownArgs, runTsdown } from '#auklet/build/runTsdown';
8
- export { ModuleStyleWatcher } from '#auklet/css/watch/watcher';
9
- export { ModuleStyleBuilder } from '#auklet/css/production/builder';
8
+ export { defineKernelPackageConfigFromFile, defineKernelPackageConfigFromOptions, } from '#auklet/build/tsdownConfig';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- export { aukletDefaultOptions, aukletDefaultStyleDependencyConfig, normalizeAukletConfig, } from '#auklet/config';
2
- export { loadAukletConfig, resolveAukletConfigModule, } from '#auklet/configLoader';
1
+ export { runAukletCli } from '#auklet/cli/main';
2
+ export { runTsdown } from '#auklet/build/runTsdown';
3
+ export { loadAukletConfig } from '#auklet/configLoader';
4
+ export { defineConfig } from '#auklet/config';
3
5
  export { aukletStylePlugin } from '#auklet/css/vite/vitePlugin';
4
- export { createTsdownArgs, runTsdown } from '#auklet/build/runTsdown';
5
- export { ModuleStyleWatcher } from '#auklet/css/watch/watcher';
6
- export { ModuleStyleBuilder } from '#auklet/css/production/builder';
6
+ export { defineKernelPackageConfigFromFile, defineKernelPackageConfigFromOptions, } from '#auklet/build/tsdownConfig';
@@ -0,0 +1,5 @@
1
+ import { Logger, type LoggerOptions } from 'briefing';
2
+ export type AukletLogger = Logger;
3
+ export type CreateAukletLoggerOptions = Pick<LoggerOptions, 'scope' | 'prefix' | 'colors' | 'silent' | 'verbose' | 'sink'>;
4
+ export declare function createAukletLogger(options?: CreateAukletLoggerOptions): Logger;
5
+ export declare function createScopedAukletLogger(scope: string): Logger;
package/dist/logger.js ADDED
@@ -0,0 +1,14 @@
1
+ import { Logger } from 'briefing';
2
+ export function createAukletLogger(options = {}) {
3
+ return new Logger({
4
+ prefix: options.prefix,
5
+ scope: options.scope,
6
+ colors: options.colors,
7
+ silent: options.silent,
8
+ verbose: options.verbose,
9
+ sink: options.sink,
10
+ });
11
+ }
12
+ export function createScopedAukletLogger(scope) {
13
+ return createAukletLogger({ scope });
14
+ }
@@ -0,0 +1,7 @@
1
+ import type { AukletLogger } from '#auklet/logger';
2
+ export declare function isGitRepository(cwd: string): Promise<boolean>;
3
+ export declare function getGitShortHash(cwd: string): Promise<string | null>;
4
+ export declare function ensureGitClean(cwd: string): Promise<void>;
5
+ export declare function hasGitChanges(cwd: string): Promise<boolean>;
6
+ export declare function commitRelease(cwd: string, version: string): Promise<void>;
7
+ export declare function createVersionTag(cwd: string, version: string, logger: AukletLogger): Promise<void>;
@@ -0,0 +1,55 @@
1
+ import { execa } from 'execa';
2
+ const runGit = async (args, cwd) => {
3
+ return execa('git', args, {
4
+ cwd,
5
+ reject: false,
6
+ });
7
+ };
8
+ export async function isGitRepository(cwd) {
9
+ const result = await runGit(['rev-parse', '--is-inside-work-tree'], cwd);
10
+ return !result.exitCode && result.stdout.trim() === 'true';
11
+ }
12
+ export async function getGitShortHash(cwd) {
13
+ const result = await runGit(['rev-parse', '--short=6', 'HEAD'], cwd);
14
+ if (result.exitCode)
15
+ return null;
16
+ return result.stdout.trim() || null;
17
+ }
18
+ export async function ensureGitClean(cwd) {
19
+ const result = await runGit(['status', '--porcelain'], cwd);
20
+ if (result.exitCode) {
21
+ throw new Error('[auklet:publish] failed to check git status.');
22
+ }
23
+ if (result.stdout.trim()) {
24
+ throw new Error('[auklet:publish] git working tree must be clean before publishing.');
25
+ }
26
+ }
27
+ export async function hasGitChanges(cwd) {
28
+ const result = await runGit(['status', '--porcelain'], cwd);
29
+ if (result.exitCode) {
30
+ throw new Error('[auklet:publish] failed to check git status.');
31
+ }
32
+ return Boolean(result.stdout.trim());
33
+ }
34
+ export async function commitRelease(cwd, version) {
35
+ const addResult = await runGit(['add', '-A'], cwd);
36
+ if (addResult.exitCode) {
37
+ throw new Error('[auklet:publish] failed to stage release changes.');
38
+ }
39
+ const commitResult = await runGit(['commit', '-m', `release: ${version}`], cwd);
40
+ if (commitResult.exitCode) {
41
+ throw new Error('[auklet:publish] failed to commit release changes.');
42
+ }
43
+ }
44
+ export async function createVersionTag(cwd, version, logger) {
45
+ const tagName = `v${version}`;
46
+ const exists = await runGit(['rev-parse', '--verify', tagName], cwd);
47
+ if (!exists.exitCode) {
48
+ logger.warnOnce('git tag ', logger.version(tagName), ' already exists, skipping tag creation.');
49
+ return;
50
+ }
51
+ const result = await runGit(['tag', tagName], cwd);
52
+ if (result.exitCode) {
53
+ throw new Error(`[auklet:publish] failed to create git tag ${tagName}.`);
54
+ }
55
+ }
@@ -0,0 +1,7 @@
1
+ import type { PackageJson } from '#auklet/publish/types';
2
+ export declare function getPackageJsonPath(packageRoot: string): string;
3
+ export declare function readPackageJson(packageRoot: string): PackageJson;
4
+ export declare function writePackageJson(packageRoot: string, packageJson: PackageJson): void;
5
+ export declare function requirePackageName(packageRoot: string, packageJson: PackageJson): string;
6
+ export declare function requirePackageVersion(packageRoot: string, packageJson: PackageJson): string;
7
+ export declare function getPublishConfig(packageJson: PackageJson): import("#auklet/publish/types").PublishPackageConfig;
@@ -0,0 +1,35 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { isString } from 'aidly';
4
+ const packageJsonFile = 'package.json';
5
+ export function getPackageJsonPath(packageRoot) {
6
+ return path.join(packageRoot, packageJsonFile);
7
+ }
8
+ export function readPackageJson(packageRoot) {
9
+ const filePath = getPackageJsonPath(packageRoot);
10
+ try {
11
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
12
+ }
13
+ catch (error) {
14
+ throw new Error(`[auklet:publish] failed to read package.json at ${filePath}.`, { cause: error });
15
+ }
16
+ }
17
+ export function writePackageJson(packageRoot, packageJson) {
18
+ const filePath = getPackageJsonPath(packageRoot);
19
+ fs.writeFileSync(filePath, `${JSON.stringify(packageJson, null, 2)}\n`);
20
+ }
21
+ export function requirePackageName(packageRoot, packageJson) {
22
+ if (isString(packageJson.name) && packageJson.name) {
23
+ return packageJson.name;
24
+ }
25
+ throw new Error(`[auklet:publish] package.json#name is required at ${packageRoot}.`);
26
+ }
27
+ export function requirePackageVersion(packageRoot, packageJson) {
28
+ if (isString(packageJson.version) && packageJson.version) {
29
+ return packageJson.version;
30
+ }
31
+ throw new Error(`[auklet:publish] package.json#version is required at ${packageRoot}.`);
32
+ }
33
+ export function getPublishConfig(packageJson) {
34
+ return packageJson.auklet?.publish ?? {};
35
+ }
@@ -0,0 +1,9 @@
1
+ import type { WorkspacePackage } from '#auklet/publish/types';
2
+ export declare function ensurePnpm(): Promise<string>;
3
+ export declare function readPnpmWorkspacePackages(root: string): Promise<WorkspacePackage[]>;
4
+ export declare function runPnpmBuild(packageRoot: string): Promise<void>;
5
+ export declare function runPnpmPublish(packageRoot: string, args: Array<string>): Promise<void>;
6
+ export declare function runPnpmOwnerAdd(packageName: string, user: string, options: {
7
+ cwd: string;
8
+ otp?: string;
9
+ }): Promise<void>;
@@ -0,0 +1,85 @@
1
+ import { isPlainObject, isString } from 'aidly';
2
+ import { execa } from 'execa';
3
+ import semver from 'semver';
4
+ import { readPnpmWorkspacePackageInfo } from '#auklet/workspace/packages';
5
+ const supportedPnpmRange = '>=10.0.0';
6
+ const runPnpm = async (args, options = {}) => {
7
+ return execa('pnpm', args, {
8
+ reject: false,
9
+ ...options,
10
+ });
11
+ };
12
+ export async function ensurePnpm() {
13
+ const result = await runPnpm(['--version']);
14
+ const stdout = String(result.stdout ?? '');
15
+ if (result.failed || !stdout) {
16
+ throw new Error('[auklet:publish] pnpm is required for publishing.\n' +
17
+ '[auklet:publish] Install pnpm first:\n' +
18
+ ' corepack enable\n' +
19
+ ' corepack prepare pnpm@10 --activate');
20
+ }
21
+ const version = stdout.trim();
22
+ if (!semver.satisfies(version, supportedPnpmRange)) {
23
+ throw new Error(`[auklet:publish] unsupported pnpm version: ${version}\n` +
24
+ `[auklet:publish] expected pnpm ${supportedPnpmRange}`);
25
+ }
26
+ return version;
27
+ }
28
+ export async function readPnpmWorkspacePackages(root) {
29
+ try {
30
+ return (await readPnpmWorkspacePackageInfo(root)).map((item) => {
31
+ if (!isWorkspacePackage(item))
32
+ throwInvalidWorkspacePackages();
33
+ return item;
34
+ });
35
+ }
36
+ catch (error) {
37
+ throw new Error('[auklet:publish] failed to read pnpm workspace packages.', { cause: error });
38
+ }
39
+ }
40
+ export async function runPnpmBuild(packageRoot) {
41
+ const result = await runPnpm(['run', 'build'], {
42
+ cwd: packageRoot,
43
+ stdio: 'inherit',
44
+ });
45
+ if (result.exitCode) {
46
+ throw new Error(`[auklet:publish] build failed at ${packageRoot}.`);
47
+ }
48
+ }
49
+ export async function runPnpmPublish(packageRoot, args) {
50
+ const result = await runPnpm(['publish', ...args], {
51
+ cwd: packageRoot,
52
+ stdio: 'inherit',
53
+ });
54
+ if (result.exitCode) {
55
+ throw new Error(`[auklet:publish] pnpm publish failed at ${packageRoot}.`);
56
+ }
57
+ }
58
+ export async function runPnpmOwnerAdd(packageName, user, options) {
59
+ const args = ['owner', 'add', user, packageName];
60
+ if (options.otp)
61
+ args.push('--otp', options.otp);
62
+ const result = await runPnpm(args, {
63
+ cwd: options.cwd,
64
+ stdio: 'inherit',
65
+ });
66
+ if (result.exitCode) {
67
+ throw new Error(`[auklet:publish] pnpm owner add failed for ${user} -> ${packageName}.`);
68
+ }
69
+ }
70
+ const isWorkspacePackage = (value) => {
71
+ if (!isPlainObject(value)) {
72
+ return false;
73
+ }
74
+ return (isString(value.name) &&
75
+ value.name.length > 0 &&
76
+ isString(value.path) &&
77
+ value.path.length > 0 &&
78
+ isString(value.version) &&
79
+ value.version.length > 0 &&
80
+ (value.private === undefined || typeof value.private === 'boolean'));
81
+ };
82
+ function throwInvalidWorkspacePackages() {
83
+ throw new Error('[auklet:publish] failed to read pnpm workspace packages.\n' +
84
+ '[auklet:publish] Expected `pnpm list -r --depth -1 --json` to return package objects with name/path/version.');
85
+ }
@@ -0,0 +1,4 @@
1
+ import type { PublishOptions, PublishTarget } from '#auklet/publish/types';
2
+ export declare class PnpmPublishApi {
3
+ publish(target: PublishTarget, options: PublishOptions): Promise<void>;
4
+ }
@@ -0,0 +1,7 @@
1
+ import { runPnpmPublish } from '#auklet/publish/api/pnpmApi';
2
+ import { createPublishArgs } from '#auklet/publish/api/publishArgs';
3
+ export class PnpmPublishApi {
4
+ async publish(target, options) {
5
+ await runPnpmPublish(target.packageRoot, createPublishArgs(target, options));
6
+ }
7
+ }
@@ -0,0 +1,2 @@
1
+ import type { PublishOptions, PublishTarget } from '#auklet/publish/types';
2
+ export declare function createPublishArgs(target: PublishTarget, options: PublishOptions): string[];
@@ -0,0 +1,25 @@
1
+ export function createPublishArgs(target, options) {
2
+ const args = ['--no-git-checks'];
3
+ if (options.dryRun)
4
+ args.push('--dry-run');
5
+ if (options.otp)
6
+ args.push('--otp', options.otp);
7
+ if (options.ignoreScripts)
8
+ args.push('--ignore-scripts');
9
+ if (shouldAddPublicAccess(target))
10
+ args.push('--access', 'public');
11
+ const tag = getPublishTag(options.version);
12
+ if (tag)
13
+ args.push('--tag', tag);
14
+ return args;
15
+ }
16
+ const shouldAddPublicAccess = (target) => {
17
+ return (target.packageName.startsWith('@') &&
18
+ !target.private &&
19
+ !target.packageJson.publishConfig?.access);
20
+ };
21
+ const getPublishTag = (versionSpec) => {
22
+ if (versionSpec === 'alpha' || versionSpec === 'beta')
23
+ return versionSpec;
24
+ return null;
25
+ };
@@ -0,0 +1,10 @@
1
+ import type { HookStatus, HookResult, PublishPlan, PublishTarget } from '#auklet/publish/types';
2
+ type RunPublishHookOptions = {
3
+ status: HookStatus;
4
+ plan: PublishPlan;
5
+ result?: HookResult;
6
+ failedTarget?: PublishTarget;
7
+ error?: unknown;
8
+ };
9
+ export declare function runPublishHook(options: RunPublishHookOptions): Promise<void>;
10
+ export {};
@@ -0,0 +1,53 @@
1
+ import { isArray } from 'aidly';
2
+ import { execa } from 'execa';
3
+ export async function runPublishHook(options) {
4
+ const hook = getHook(options.plan.config, options.status);
5
+ if (!hook)
6
+ return;
7
+ const commands = isArray(hook) ? hook : [hook];
8
+ for (const command of commands) {
9
+ const result = await execa(command, {
10
+ cwd: options.plan.root,
11
+ shell: true,
12
+ stdio: 'inherit',
13
+ reject: false,
14
+ env: createHookEnv(options),
15
+ });
16
+ if (result.exitCode) {
17
+ throw new Error(`[auklet:publish] publish ${options.status} hook failed: ${command}`);
18
+ }
19
+ }
20
+ }
21
+ const getHook = (config, status) => {
22
+ if (status === 'beforeBuild')
23
+ return config.beforeBuild;
24
+ if (status === 'afterBuild')
25
+ return config.afterBuild;
26
+ if (status === 'beforePublish')
27
+ return config.beforePublish;
28
+ return config.afterPublish;
29
+ };
30
+ const createHookEnv = (options) => {
31
+ const env = {
32
+ AUKLET_PUBLISH_STATUS: options.status,
33
+ AUKLET_PUBLISH_RESULT: options.result ?? '',
34
+ AUKLET_PUBLISH_VERSION: options.plan.version,
35
+ AUKLET_PUBLISH_DRY_RUN: options.plan.dryRun ? 'true' : 'false',
36
+ AUKLET_PUBLISH_ROOT: options.plan.root,
37
+ AUKLET_PUBLISH_PACKAGES: options.plan.targets
38
+ .map((target) => target.packageName)
39
+ .join(','),
40
+ };
41
+ if (options.failedTarget) {
42
+ env.AUKLET_PUBLISH_FAILED_PACKAGE = options.failedTarget.packageName;
43
+ }
44
+ if (options.error) {
45
+ env.AUKLET_PUBLISH_ERROR = getErrorMessage(options.error);
46
+ }
47
+ return env;
48
+ };
49
+ const getErrorMessage = (error) => {
50
+ if (error instanceof Error)
51
+ return error.message;
52
+ return String(error);
53
+ };
@@ -0,0 +1,2 @@
1
+ export declare function runPublishCli(args: Array<string>): Promise<void>;
2
+ export declare function runOwnerCli(args: Array<string>): Promise<void>;
@@ -0,0 +1,95 @@
1
+ import minimist from 'minimist';
2
+ import { isArray } from 'aidly';
3
+ import { OwnerRunner } from '#auklet/publish/ownerRunner';
4
+ import { PublishRunner } from '#auklet/publish/publishRunner';
5
+ import { ensurePnpm } from '#auklet/publish/api/pnpmApi';
6
+ const publishFlags = new Set([
7
+ '_',
8
+ 'filter',
9
+ 'version',
10
+ 'dry-run',
11
+ 'format',
12
+ 'otp',
13
+ 'ignore-scripts',
14
+ 'allow-dirty',
15
+ ]);
16
+ const ownerFlags = new Set(['_', 'filter', 'package', 'otp']);
17
+ export async function runPublishCli(args) {
18
+ const cliArgs = stripLeadingArgsSeparator(args);
19
+ validateNoPrefixedFlags(cliArgs, new Set(['--no-format']));
20
+ const argv = minimist(cliArgs, {
21
+ string: ['filter', 'version', 'otp'],
22
+ boolean: ['dry-run', 'format', 'ignore-scripts', 'allow-dirty'],
23
+ default: {
24
+ format: true,
25
+ },
26
+ });
27
+ validateFlags(argv, publishFlags);
28
+ if (argv._.length) {
29
+ throw new Error(`[auklet:publish] unknown publish argument: ${argv._.join(' ')}`);
30
+ }
31
+ await ensurePnpm();
32
+ await new PublishRunner({
33
+ cwd: process.cwd(),
34
+ filters: toArray(argv.filter),
35
+ version: stringOption(argv.version),
36
+ dryRun: argv['dry-run'] === true,
37
+ format: argv.format !== false,
38
+ otp: stringOption(argv.otp),
39
+ ignoreScripts: argv['ignore-scripts'] === true,
40
+ allowDirty: argv['allow-dirty'] === true,
41
+ }).run();
42
+ }
43
+ export async function runOwnerCli(args) {
44
+ const cliArgs = stripLeadingArgsSeparator(args);
45
+ validateNoPrefixedFlags(cliArgs, new Set());
46
+ const argv = minimist(cliArgs, {
47
+ string: ['filter', 'package', 'otp'],
48
+ });
49
+ validateFlags(argv, ownerFlags);
50
+ const [subcommand, ...users] = argv._;
51
+ if (subcommand !== 'add') {
52
+ throw new Error('[auklet:publish] expected owner command: auk owner add <user...>');
53
+ }
54
+ if (!users.length) {
55
+ throw new Error('[auklet:publish] owner add requires at least one user.');
56
+ }
57
+ await ensurePnpm();
58
+ await new OwnerRunner({
59
+ cwd: process.cwd(),
60
+ users,
61
+ filters: toArray(argv.filter),
62
+ packages: toArray(argv.package),
63
+ otp: stringOption(argv.otp),
64
+ }).run();
65
+ }
66
+ const validateFlags = (argv, allowedFlags) => {
67
+ for (const flag of Object.keys(argv)) {
68
+ if (!allowedFlags.has(flag)) {
69
+ throw new Error(`[auklet:publish] unknown option: --${flag}`);
70
+ }
71
+ }
72
+ };
73
+ const validateNoPrefixedFlags = (args, allowedFlags) => {
74
+ const flag = args.find((arg) => arg.startsWith('--no-') && !allowedFlags.has(arg));
75
+ if (flag) {
76
+ throw new Error(`[auklet:publish] unknown option: ${flag}`);
77
+ }
78
+ };
79
+ const stripLeadingArgsSeparator = (args) => {
80
+ return args.filter((arg) => arg !== '--');
81
+ };
82
+ const toArray = (value) => {
83
+ if (value === undefined)
84
+ return [];
85
+ return isArray(value)
86
+ ? value.map(String).filter(Boolean)
87
+ : [String(value)].filter(Boolean);
88
+ };
89
+ const stringOption = (value) => {
90
+ if (value === undefined)
91
+ return undefined;
92
+ if (isArray(value))
93
+ return String(value.at(-1));
94
+ return String(value);
95
+ };
@@ -0,0 +1,6 @@
1
+ import type { OwnerOptions } from '#auklet/publish/types';
2
+ export declare class OwnerRunner {
3
+ private readonly options;
4
+ constructor(options: OwnerOptions);
5
+ run(): Promise<void>;
6
+ }
@@ -0,0 +1,22 @@
1
+ import { runPnpmOwnerAdd } from '#auklet/publish/api/pnpmApi';
2
+ import { resolveOwnerPackageNames } from '#auklet/publish/targetResolver';
3
+ export class OwnerRunner {
4
+ options;
5
+ constructor(options) {
6
+ this.options = options;
7
+ }
8
+ async run() {
9
+ const packageNames = await resolveOwnerPackageNames(this.options);
10
+ if (!packageNames.length) {
11
+ throw new Error('[auklet:publish] no owner target package found.');
12
+ }
13
+ for (const packageName of packageNames) {
14
+ for (const user of this.options.users) {
15
+ await runPnpmOwnerAdd(packageName, user, {
16
+ cwd: this.options.cwd,
17
+ otp: this.options.otp,
18
+ });
19
+ }
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,16 @@
1
+ import type { PublishOptions } from '#auklet/publish/types';
2
+ export declare class PublishRunner {
3
+ private readonly git;
4
+ private readonly publisher;
5
+ private readonly preflight;
6
+ private readonly versions;
7
+ private readonly logger;
8
+ private readonly summaryLogger;
9
+ private readonly options;
10
+ constructor(options: PublishOptions);
11
+ run(): Promise<void>;
12
+ private preparePlan;
13
+ private publishWithPlan;
14
+ private handleFailure;
15
+ private runAfterPublishSuccess;
16
+ }