auklet 0.0.18 → 0.0.20

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 (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +255 -174
  3. package/bin/entry.mjs +5 -0
  4. package/dist/build/bundleConfig.js +1 -1
  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/css/production/buildReporter.d.ts +3 -0
  31. package/dist/css/production/buildReporter.js +19 -0
  32. package/dist/css/production/builder.d.ts +8 -3
  33. package/dist/css/production/builder.js +9 -13
  34. package/dist/css/vite/hmr.js +7 -6
  35. package/dist/css/vite/moduleGraph/graph.js +0 -1
  36. package/dist/css/vite/moduleGraph/packageSource/monorepo.d.ts +5 -1
  37. package/dist/css/vite/moduleGraph/packageSource/monorepo.js +40 -31
  38. package/dist/css/vite/moduleGraph/types.d.ts +0 -1
  39. package/dist/css/watch/watcher.d.ts +0 -1
  40. package/dist/css/watch/watcher.js +3 -10
  41. package/dist/index.d.ts +5 -7
  42. package/dist/index.js +4 -5
  43. package/dist/logger.d.ts +5 -0
  44. package/dist/logger.js +14 -0
  45. package/dist/publish/api/gitApi.d.ts +7 -0
  46. package/dist/publish/api/gitApi.js +55 -0
  47. package/dist/publish/api/packageJsonApi.d.ts +7 -0
  48. package/dist/publish/api/packageJsonApi.js +34 -0
  49. package/dist/publish/api/pnpmApi.d.ts +9 -0
  50. package/dist/publish/api/pnpmApi.js +85 -0
  51. package/dist/publish/api/pnpmPublishApi.d.ts +4 -0
  52. package/dist/publish/api/pnpmPublishApi.js +7 -0
  53. package/dist/publish/api/publishArgs.d.ts +2 -0
  54. package/dist/publish/api/publishArgs.js +25 -0
  55. package/dist/publish/api/publishHookApi.d.ts +10 -0
  56. package/dist/publish/api/publishHookApi.js +52 -0
  57. package/dist/publish/cli.d.ts +2 -0
  58. package/dist/publish/cli.js +94 -0
  59. package/dist/publish/ownerRunner.d.ts +6 -0
  60. package/dist/publish/ownerRunner.js +22 -0
  61. package/dist/publish/publishRunner.d.ts +16 -0
  62. package/dist/publish/publishRunner.js +108 -0
  63. package/dist/publish/runner/packageBuilder.d.ts +4 -0
  64. package/dist/publish/runner/packageBuilder.js +15 -0
  65. package/dist/publish/runner/packagePublisher.d.ts +7 -0
  66. package/dist/publish/runner/packagePublisher.js +21 -0
  67. package/dist/publish/runner/publishFailureReporter.d.ts +3 -0
  68. package/dist/publish/runner/publishFailureReporter.js +14 -0
  69. package/dist/publish/runner/publishOutputFormatter.d.ts +2 -0
  70. package/dist/publish/runner/publishOutputFormatter.js +83 -0
  71. package/dist/publish/runner/publishPreflight.d.ts +8 -0
  72. package/dist/publish/runner/publishPreflight.js +26 -0
  73. package/dist/publish/runner/publishSummaryReporter.d.ts +10 -0
  74. package/dist/publish/runner/publishSummaryReporter.js +81 -0
  75. package/dist/publish/runner/publishTargetError.d.ts +9 -0
  76. package/dist/publish/runner/publishTargetError.js +14 -0
  77. package/dist/publish/runner/releaseGitController.d.ts +10 -0
  78. package/dist/publish/runner/releaseGitController.js +41 -0
  79. package/dist/publish/runner/versionWriter.d.ts +13 -0
  80. package/dist/publish/runner/versionWriter.js +78 -0
  81. package/dist/publish/targetResolver.d.ts +7 -0
  82. package/dist/publish/targetResolver.js +195 -0
  83. package/dist/publish/types.d.ts +70 -0
  84. package/dist/publish/types.js +0 -0
  85. package/dist/publish/version.d.ts +5 -0
  86. package/dist/publish/version.js +55 -0
  87. package/dist/types.d.ts +8 -7
  88. package/dist/workspace/packages.d.ts +9 -0
  89. package/dist/workspace/packages.js +62 -0
  90. package/dist/workspace/root.d.ts +1 -0
  91. package/dist/workspace/root.js +14 -0
  92. package/package.json +15 -6
  93. package/bin/entry.cjs +0 -163
@@ -0,0 +1,78 @@
1
+ import { readPackageJson, writePackageJson, } from '#auklet/publish/api/packageJsonApi';
2
+ export class VersionWriter {
3
+ options;
4
+ logger;
5
+ constructor(options, logger) {
6
+ this.options = options;
7
+ this.logger = logger;
8
+ }
9
+ writeBeforeBuild(plan) {
10
+ if (!plan.dryRun && this.options.version) {
11
+ this.writeVersions(plan);
12
+ }
13
+ }
14
+ logDryRunPlan(plan) {
15
+ if (!plan.dryRun || !this.options.version)
16
+ return;
17
+ const logger = this.logger;
18
+ logger.info('dry-run mode: package.json files will not be changed');
19
+ if (plan.workspaceMode === 'monorepo') {
20
+ const rootPackageJson = readPackageJson(plan.root);
21
+ logger.summary({
22
+ title: 'Publish dry-run plan',
23
+ values: {
24
+ mode: plan.workspaceMode,
25
+ sharedVersion: this.formatVersionChange(rootPackageJson.version, plan.version),
26
+ targets: plan.targets.length,
27
+ },
28
+ });
29
+ for (const target of plan.targets) {
30
+ logger.info('planned package ', this.formatPackage(target.packageName), ': ', ...this.formatVersionChange(target.version, target.publishVersion));
31
+ }
32
+ logger.info('builds will still read each package.json#version');
33
+ logger.info('pnpm publish --dry-run will still read each package.json#version');
34
+ return;
35
+ }
36
+ const [target] = plan.targets;
37
+ if (target) {
38
+ logger.summary({
39
+ title: 'Publish dry-run plan',
40
+ values: {
41
+ package: this.formatPackage(target.packageName),
42
+ version: this.formatVersionChange(target.version, target.publishVersion),
43
+ },
44
+ });
45
+ logger.info(`build will still read package.json#version: ${target.version}`);
46
+ logger.info(`pnpm publish --dry-run will still read package.json#version: ${target.version}`);
47
+ }
48
+ }
49
+ logWrittenVersionFailure(plan) {
50
+ if (!plan.dryRun && this.options.version) {
51
+ this.logger.error('package.json versions may have been written. Auklet will not roll them back; check publish output before retrying.');
52
+ }
53
+ }
54
+ writeVersions(plan) {
55
+ const packageRoots = new Set([
56
+ plan.root,
57
+ ...plan.targets.map((target) => target.packageRoot),
58
+ ]);
59
+ for (const packageRoot of packageRoots) {
60
+ const packageJson = readPackageJson(packageRoot);
61
+ const packageName = plan.targets.find((target) => target.packageRoot === packageRoot)
62
+ ?.packageName ?? (packageRoot === plan.root ? 'root' : packageRoot);
63
+ if (packageJson.version !== plan.version) {
64
+ this.logger.info('writing version ', this.formatPackage(packageName), ': ', ...this.formatVersionChange(packageJson.version, plan.version));
65
+ }
66
+ packageJson.version = plan.version;
67
+ writePackageJson(packageRoot, packageJson);
68
+ }
69
+ }
70
+ formatPackage(packageName) {
71
+ return this.logger.package(packageName);
72
+ }
73
+ formatVersionChange(from, to) {
74
+ const logger = this.logger;
75
+ const fromVersion = String(from);
76
+ return [logger.version(fromVersion), ' -> ', logger.version(to)];
77
+ }
78
+ }
@@ -0,0 +1,7 @@
1
+ import { type AukletLogger } from '#auklet/logger';
2
+ import type { OwnerOptions, PublishOptions, PublishPlan } from '#auklet/publish/types';
3
+ type ResolvePublishTargetsOptions = Pick<PublishOptions, 'cwd' | 'filters' | 'version' | 'dryRun'>;
4
+ type ResolveOwnerTargetsOptions = Pick<OwnerOptions, 'cwd' | 'filters' | 'packages'>;
5
+ export declare function resolvePublishPlan(options: ResolvePublishTargetsOptions, logger?: AukletLogger): Promise<PublishPlan>;
6
+ export declare function resolveOwnerPackageNames(options: ResolveOwnerTargetsOptions): Promise<string[]>;
7
+ export {};
@@ -0,0 +1,195 @@
1
+ import path from 'node:path';
2
+ import { createScopedAukletLogger } from '#auklet/logger';
3
+ import { findWorkspaceRoot } from '#auklet/workspace/root';
4
+ import { getPublishConfig, readPackageJson, requirePackageName, requirePackageVersion, } from '#auklet/publish/api/packageJsonApi';
5
+ import { readPnpmWorkspacePackages } from '#auklet/publish/api/pnpmApi';
6
+ import { resolvePublishVersion, validateVersionConsistency, } from '#auklet/publish/version';
7
+ export async function resolvePublishPlan(options, logger = createScopedAukletLogger('publish')) {
8
+ if (options.filters.length) {
9
+ return resolveMonorepoPublishPlan(options, logger);
10
+ }
11
+ return resolveCurrentPackagePublishPlan(options);
12
+ }
13
+ export async function resolveOwnerPackageNames(options) {
14
+ if (options.filters.length && options.packages.length) {
15
+ throw new Error('[auklet:publish] owner command cannot use --filter and --package together.');
16
+ }
17
+ if (options.filters.length) {
18
+ const root = requireWorkspaceRoot(options.cwd);
19
+ const packages = await readPnpmWorkspacePackages(root);
20
+ return filterWorkspacePackages(packages, options.filters)
21
+ .filter((item) => !item.private)
22
+ .map((item) => item.name);
23
+ }
24
+ if (options.packages.length)
25
+ return [...new Set(options.packages)];
26
+ const packageJson = readPackageJson(options.cwd);
27
+ if (packageJson.private) {
28
+ throw new Error('[auklet:publish] current package is private.');
29
+ }
30
+ return [requirePackageName(options.cwd, packageJson)];
31
+ }
32
+ const resolveCurrentPackagePublishPlan = async (options) => {
33
+ const packageRoot = path.resolve(options.cwd);
34
+ const packageJson = readPackageJson(packageRoot);
35
+ const version = requirePackageVersion(packageRoot, packageJson);
36
+ const workspaceRoot = findWorkspaceRoot(packageRoot);
37
+ if (workspaceRoot === packageRoot && packageJson.private) {
38
+ throw new Error('[auklet:publish] current directory is a private monorepo root. Use --filter to select workspace packages.');
39
+ }
40
+ const publishVersion = await resolvePublishVersion(version, options.version, packageRoot);
41
+ const target = createPublishTarget({
42
+ packageRoot,
43
+ packageJson,
44
+ publishVersion,
45
+ workspaceMode: 'single',
46
+ });
47
+ validatePublishTargets([target]);
48
+ return {
49
+ root: packageRoot,
50
+ version: publishVersion,
51
+ dryRun: options.dryRun,
52
+ targets: [target],
53
+ config: getPublishConfig(packageJson),
54
+ workspaceMode: 'single',
55
+ };
56
+ };
57
+ const resolveMonorepoPublishPlan = async (options, logger) => {
58
+ const root = requireWorkspaceRoot(options.cwd);
59
+ const rootPackageJson = readPackageJson(root);
60
+ const rootVersion = requirePackageVersion(root, rootPackageJson);
61
+ const workspacePackages = await readPnpmWorkspacePackages(root);
62
+ const selectedPackages = filterWorkspacePackages(workspacePackages, options.filters);
63
+ const publishVersion = await resolvePublishVersion(rootVersion, options.version, root);
64
+ const targets = selectedPackages
65
+ .filter((item) => {
66
+ if (!item.private)
67
+ return true;
68
+ if (isExactlyMatchedByFilter(item.name, options.filters)) {
69
+ logger.warnOnce('package ', logger.package(item.name), ' is private, skipping.');
70
+ }
71
+ return false;
72
+ })
73
+ .map((item) => {
74
+ const packageJson = readPackageJson(item.path);
75
+ return createPublishTarget({
76
+ packageRoot: item.path,
77
+ packageJson,
78
+ publishVersion,
79
+ workspaceMode: 'monorepo',
80
+ });
81
+ });
82
+ validatePublishTargets(targets);
83
+ validateWorkspaceInternalDependencies(targets);
84
+ if (!options.version) {
85
+ validateVersionConsistency(rootVersion, targets);
86
+ }
87
+ return {
88
+ root,
89
+ version: publishVersion,
90
+ dryRun: options.dryRun,
91
+ targets: sortTargetsByWorkspaceDependencies(targets),
92
+ config: getPublishConfig(rootPackageJson),
93
+ workspaceMode: 'monorepo',
94
+ };
95
+ };
96
+ const requireWorkspaceRoot = (cwd) => {
97
+ const root = findWorkspaceRoot(cwd);
98
+ if (!root) {
99
+ throw new Error('[auklet:publish] --filter requires a pnpm workspace root.');
100
+ }
101
+ return root;
102
+ };
103
+ const filterWorkspacePackages = (packages, filters) => {
104
+ const matched = packages.filter((item) => filters.some((filter) => matchesFilter(item.name, filter)));
105
+ if (!matched.length) {
106
+ throw new Error(`[auklet:publish] no workspace package matched filter: ${filters.join(', ')}`);
107
+ }
108
+ return matched;
109
+ };
110
+ const matchesFilter = (packageName, filter) => {
111
+ if (filter.endsWith('/*')) {
112
+ const scope = filter.slice(0, -2);
113
+ return packageName.startsWith(`${scope}/`);
114
+ }
115
+ return packageName === filter;
116
+ };
117
+ const isExactlyMatchedByFilter = (packageName, filters) => {
118
+ return filters.some((filter) => filter === packageName);
119
+ };
120
+ const createPublishTarget = (options) => {
121
+ const packageName = requirePackageName(options.packageRoot, options.packageJson);
122
+ const version = requirePackageVersion(options.packageRoot, options.packageJson);
123
+ return {
124
+ packageRoot: options.packageRoot,
125
+ packageName,
126
+ version,
127
+ publishVersion: options.publishVersion,
128
+ private: options.packageJson.private === true,
129
+ kind: 'package',
130
+ workspaceMode: options.workspaceMode,
131
+ packageJson: options.packageJson,
132
+ };
133
+ };
134
+ const validatePublishTargets = (targets) => {
135
+ const publishableTargets = targets.filter((target) => !target.private);
136
+ if (!publishableTargets.length) {
137
+ throw new Error('[auklet:publish] no publishable package found.');
138
+ }
139
+ };
140
+ const sortTargetsByWorkspaceDependencies = (targets) => {
141
+ const targetNames = new Set(targets.map((target) => target.packageName));
142
+ const visited = new Set();
143
+ const visiting = new Set();
144
+ const sorted = [];
145
+ const targetMap = new Map(targets.map((target) => [target.packageName, target]));
146
+ const visit = (target) => {
147
+ if (visited.has(target.packageName))
148
+ return;
149
+ if (visiting.has(target.packageName)) {
150
+ throw new Error(`[auklet:publish] circular workspace dependency detected at ${target.packageName}.`);
151
+ }
152
+ visiting.add(target.packageName);
153
+ for (const dependency of getWorkspaceDependencies(target.packageJson)) {
154
+ if (!targetNames.has(dependency))
155
+ continue;
156
+ const dependencyTarget = targetMap.get(dependency);
157
+ if (dependencyTarget)
158
+ visit(dependencyTarget);
159
+ }
160
+ visiting.delete(target.packageName);
161
+ visited.add(target.packageName);
162
+ sorted.push(target);
163
+ };
164
+ for (const target of targets) {
165
+ visit(target);
166
+ }
167
+ return sorted;
168
+ };
169
+ const getWorkspaceDependencies = (packageJson) => {
170
+ return Object.entries({
171
+ ...packageJson.dependencies,
172
+ ...packageJson.optionalDependencies,
173
+ })
174
+ .filter(([, version]) => version === 'workspace:*')
175
+ .map(([packageName]) => packageName);
176
+ };
177
+ const validateWorkspaceInternalDependencies = (targets) => {
178
+ const targetNames = new Set(targets.map((target) => target.packageName));
179
+ for (const target of targets) {
180
+ for (const dependencyGroup of workspaceDependencyGroups) {
181
+ for (const [packageName, version] of Object.entries(target.packageJson[dependencyGroup] ?? {})) {
182
+ if (!targetNames.has(packageName))
183
+ continue;
184
+ if (version === 'workspace:*')
185
+ continue;
186
+ throw new Error(`[auklet:publish] package ${target.packageName} ${dependencyGroup} ${packageName} must use workspace:* before publishing.`);
187
+ }
188
+ }
189
+ }
190
+ };
191
+ const workspaceDependencyGroups = [
192
+ 'dependencies',
193
+ 'optionalDependencies',
194
+ 'peerDependencies',
195
+ ];
@@ -0,0 +1,70 @@
1
+ export type PackageJson = {
2
+ name?: string;
3
+ version?: string;
4
+ private?: boolean;
5
+ scripts?: Record<string, string>;
6
+ files?: Array<string>;
7
+ publishConfig?: {
8
+ access?: string;
9
+ [key: string]: unknown;
10
+ };
11
+ auklet?: {
12
+ publish?: PublishPackageConfig;
13
+ [key: string]: unknown;
14
+ };
15
+ dependencies?: Record<string, string>;
16
+ devDependencies?: Record<string, string>;
17
+ peerDependencies?: Record<string, string>;
18
+ optionalDependencies?: Record<string, string>;
19
+ [key: string]: unknown;
20
+ };
21
+ export type PublishPackageConfig = {
22
+ beforeBuild?: PublishHookConfig;
23
+ afterBuild?: PublishHookConfig;
24
+ beforePublish?: PublishHookConfig;
25
+ afterPublish?: PublishHookConfig;
26
+ };
27
+ export type PublishHookConfig = string | Array<string>;
28
+ export type PublishTarget = {
29
+ packageRoot: string;
30
+ packageName: string;
31
+ version: string;
32
+ publishVersion: string;
33
+ private: boolean;
34
+ kind: 'package' | 'lib';
35
+ workspaceMode: 'single' | 'monorepo';
36
+ packageJson: PackageJson;
37
+ };
38
+ export type WorkspacePackage = {
39
+ name: string;
40
+ path: string;
41
+ version: string;
42
+ private?: boolean;
43
+ };
44
+ export type PublishOptions = {
45
+ cwd: string;
46
+ filters: Array<string>;
47
+ version?: string;
48
+ dryRun: boolean;
49
+ format: boolean;
50
+ otp?: string;
51
+ ignoreScripts: boolean;
52
+ allowDirty: boolean;
53
+ };
54
+ export type OwnerOptions = {
55
+ cwd: string;
56
+ users: Array<string>;
57
+ filters: Array<string>;
58
+ packages: Array<string>;
59
+ otp?: string;
60
+ };
61
+ export type PublishPlan = {
62
+ root: string;
63
+ version: string;
64
+ dryRun: boolean;
65
+ targets: Array<PublishTarget>;
66
+ config: PublishPackageConfig;
67
+ workspaceMode: 'single' | 'monorepo';
68
+ };
69
+ export type HookStatus = 'beforeBuild' | 'afterBuild' | 'beforePublish' | 'afterPublish';
70
+ export type HookResult = 'success' | 'failure';
File without changes
@@ -0,0 +1,5 @@
1
+ export declare function resolvePublishVersion(currentVersion: string, versionSpec: string | undefined, cwd: string): Promise<string>;
2
+ export declare function validateVersionConsistency(expectedVersion: string, versions: Array<{
3
+ packageName: string;
4
+ version: string;
5
+ }>): void;
@@ -0,0 +1,55 @@
1
+ import semver from 'semver';
2
+ import { getGitShortHash } from '#auklet/publish/api/gitApi';
3
+ const prereleaseKinds = new Set(['alpha', 'beta']);
4
+ const releaseIncrements = new Set(['patch', 'minor', 'major']);
5
+ export async function resolvePublishVersion(currentVersion, versionSpec, cwd) {
6
+ if (!versionSpec) {
7
+ if (!semver.valid(currentVersion)) {
8
+ throw new Error(`[auklet:publish] invalid package version: ${currentVersion}`);
9
+ }
10
+ return currentVersion;
11
+ }
12
+ if (releaseIncrements.has(versionSpec)) {
13
+ const parsed = semver.parse(currentVersion);
14
+ if (!parsed) {
15
+ throw new Error(`[auklet:publish] invalid package version: ${currentVersion}`);
16
+ }
17
+ const baseVersion = `${parsed.major}.${parsed.minor}.${parsed.patch}`;
18
+ const next = semver.inc(baseVersion, versionSpec);
19
+ if (!next) {
20
+ throw new Error(`[auklet:publish] failed to bump version ${currentVersion} with ${versionSpec}.`);
21
+ }
22
+ return next;
23
+ }
24
+ if (prereleaseKinds.has(versionSpec)) {
25
+ const parsed = semver.parse(currentVersion);
26
+ if (!parsed) {
27
+ throw new Error(`[auklet:publish] invalid package version: ${currentVersion}`);
28
+ }
29
+ const suffix = (await getGitShortHash(cwd)) ?? createTimestamp();
30
+ return `${parsed.major}.${parsed.minor}.${parsed.patch}-${versionSpec}.${suffix}`;
31
+ }
32
+ const explicit = semver.valid(versionSpec);
33
+ if (explicit)
34
+ return explicit;
35
+ throw new Error(`[auklet:publish] unsupported --version value: ${versionSpec}`);
36
+ }
37
+ export function validateVersionConsistency(expectedVersion, versions) {
38
+ for (const item of versions) {
39
+ if (item.version !== expectedVersion) {
40
+ throw new Error(`[auklet:publish] package ${item.packageName} version ${item.version} does not match shared version ${expectedVersion}.`);
41
+ }
42
+ }
43
+ }
44
+ const createTimestamp = () => {
45
+ const date = new Date();
46
+ const pad = (value) => value.toString().padStart(2, '0');
47
+ return [
48
+ date.getFullYear(),
49
+ pad(date.getMonth() + 1),
50
+ pad(date.getDate()),
51
+ pad(date.getHours()),
52
+ pad(date.getMinutes()),
53
+ pad(date.getSeconds()),
54
+ ].join('');
55
+ };
package/dist/types.d.ts CHANGED
@@ -53,11 +53,6 @@ export interface AukletConfig {
53
53
  styles?: StyleOptions;
54
54
  build?: PackageBuildOptions;
55
55
  }
56
- export type AukletLogger = {
57
- log?: (...args: Array<unknown>) => void;
58
- info?: (...args: Array<unknown>) => void;
59
- error?: (...args: Array<unknown>) => void;
60
- };
61
56
  export type LoadAukletConfigOptions = {
62
57
  configFile?: string;
63
58
  cacheBust?: boolean;
@@ -65,7 +60,6 @@ export type LoadAukletConfigOptions = {
65
60
  export interface ModuleStyleBuildContext {
66
61
  packageRoot?: string;
67
62
  aukletConfig?: AukletConfig;
68
- logger?: AukletLogger;
69
63
  source?: string;
70
64
  output?: string;
71
65
  }
@@ -76,7 +70,14 @@ export interface ResolvedModuleStyleBuildContext {
76
70
  }
77
71
  export type ModuleStyleBuildOptions = {
78
72
  aukletConfig?: AukletConfig;
79
- logger?: AukletLogger;
73
+ };
74
+ export type ModuleStyleBuildResult = {
75
+ packageRoot: string;
76
+ styleFiles: Array<string>;
77
+ outputs: Array<{
78
+ file: string;
79
+ size: number;
80
+ }>;
80
81
  };
81
82
  export interface ModuleStyleBuildOutputConfig {
82
83
  outputFormats: Array<string>;
@@ -0,0 +1,9 @@
1
+ import { type Options } from 'execa';
2
+ export type WorkspacePackageInfo = {
3
+ name: string;
4
+ path: string;
5
+ version?: string;
6
+ private?: boolean;
7
+ };
8
+ export declare function readPnpmWorkspacePackageInfo(root: string, options?: Options): Promise<WorkspacePackageInfo[]>;
9
+ export declare function readPnpmWorkspacePackageInfoSync(root: string): WorkspacePackageInfo[];
@@ -0,0 +1,62 @@
1
+ import { execa, execaSync } from 'execa';
2
+ import { isArray, isPlainObject, isString } from 'aidly';
3
+ const pnpmWorkspaceListArgs = ['list', '-r', '--depth', '-1', '--json'];
4
+ const parsePnpmWorkspacePackages = (value) => {
5
+ let parsed;
6
+ try {
7
+ parsed = JSON.parse(value);
8
+ }
9
+ catch (error) {
10
+ throw new Error('[auklet:workspace] failed to parse workspace packages.', {
11
+ cause: error,
12
+ });
13
+ }
14
+ if (!isArray(parsed)) {
15
+ throwInvalidWorkspacePackages();
16
+ }
17
+ return parsed.map((item) => {
18
+ if (!isWorkspacePackageInfo(item))
19
+ throwInvalidWorkspacePackages();
20
+ return item;
21
+ });
22
+ };
23
+ export async function readPnpmWorkspacePackageInfo(root, options = {}) {
24
+ const result = await execa('pnpm', pnpmWorkspaceListArgs, {
25
+ cwd: root,
26
+ reject: false,
27
+ ...options,
28
+ });
29
+ if (result.failed) {
30
+ throw new Error('[auklet:workspace] failed to read workspace packages.', {
31
+ cause: result.stderr || result.stdout,
32
+ });
33
+ }
34
+ return parsePnpmWorkspacePackages(String(result.stdout ?? ''));
35
+ }
36
+ export function readPnpmWorkspacePackageInfoSync(root) {
37
+ const result = execaSync('pnpm', pnpmWorkspaceListArgs, {
38
+ cwd: root,
39
+ reject: false,
40
+ });
41
+ if (result.failed) {
42
+ throw new Error('[auklet:workspace] failed to read workspace packages.', {
43
+ cause: result.stderr || result.stdout,
44
+ });
45
+ }
46
+ return parsePnpmWorkspacePackages(String(result.stdout ?? ''));
47
+ }
48
+ const isWorkspacePackageInfo = (value) => {
49
+ if (!isPlainObject(value)) {
50
+ return false;
51
+ }
52
+ return (isString(value.name) &&
53
+ value.name.length > 0 &&
54
+ isString(value.path) &&
55
+ value.path.length > 0 &&
56
+ (value.version === undefined || isString(value.version)) &&
57
+ (value.private === undefined || typeof value.private === 'boolean'));
58
+ };
59
+ function throwInvalidWorkspacePackages() {
60
+ throw new Error('[auklet:workspace] failed to read workspace packages.\n' +
61
+ '[auklet:workspace] Expected `pnpm list -r --depth -1 --json` to return package objects with name/path.');
62
+ }
@@ -0,0 +1 @@
1
+ export declare function findWorkspaceRoot(startDir: string): string | null;
@@ -0,0 +1,14 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ const workspaceFile = 'pnpm-workspace.yaml';
4
+ export function findWorkspaceRoot(startDir) {
5
+ let current = path.resolve(startDir);
6
+ while (true) {
7
+ if (fs.existsSync(path.join(current, workspaceFile)))
8
+ return current;
9
+ const parent = path.dirname(current);
10
+ if (parent === current)
11
+ return null;
12
+ current = parent;
13
+ }
14
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auklet",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "type": "module",
5
5
  "author": "chentao.arthur",
6
6
  "description": "Build utilities for TypeScript packages and module CSS output.",
@@ -9,8 +9,8 @@
9
9
  "pnpm": "=10.27.0"
10
10
  },
11
11
  "bin": {
12
- "auk": "./bin/entry.cjs",
13
- "auklet": "./bin/entry.cjs"
12
+ "auk": "./bin/entry.mjs",
13
+ "auklet": "./bin/entry.mjs"
14
14
  },
15
15
  "exports": {
16
16
  ".": {
@@ -51,23 +51,30 @@
51
51
  "tsdown"
52
52
  ],
53
53
  "dependencies": {
54
+ "cac": "7.0.0",
54
55
  "unrun": "0.3.0",
55
- "execa": "9.6.1",
56
+ "tsdown": "0.22.0",
56
57
  "aidly": "1.37.0",
58
+ "execa": "9.6.1",
57
59
  "rimraf": "6.1.3",
58
- "tsdown": "0.22.0",
59
60
  "postcss": "8.5.15",
60
61
  "chokidar": "5.0.0",
62
+ "semver": "7.8.1",
63
+ "briefing": "0.0.4",
61
64
  "minimist": "1.2.8",
65
+ "picocolors": "1.1.1",
62
66
  "typescript": "6.0.3",
67
+ "prettier": "3.8.3",
63
68
  "conditional-export": "1.1.0"
64
69
  },
65
70
  "devDependencies": {
66
71
  "@types/node": "22.17.0",
72
+ "@types/semver": "7.7.1",
73
+ "@types/prettier": "3.0.0",
67
74
  "@types/minimist": "1.2.5",
68
75
  "@vitest/coverage-v8": "4.1.7",
69
76
  "husky": "9.1.7",
70
- "prettier": "3.8.3",
77
+ "verdaccio": "6.7.1",
71
78
  "lint-staged": "17.0.5",
72
79
  "vite": "8.0.14",
73
80
  "vitest": "4.1.7"
@@ -89,6 +96,8 @@
89
96
  "test:examples": "pnpm build:examples && vitest run examples/__tests__",
90
97
  "test:coverage": "vitest run src/__tests__ --coverage",
91
98
  "typecheck": "tsc --noEmit --skipLibCheck",
99
+ "dev:registry": "verdaccio --config examples/verdaccio.yaml --listen 127.0.0.1:4873",
100
+ "dev:registry-login": "npm adduser --registry http://127.0.0.1:4873 --auth-type=legacy",
92
101
  "dev:examples": "pnpm --filter './examples/*' --if-present dev",
93
102
  "build:examples": "pnpm --filter './examples/*' build",
94
103
  "format:md": "prettier --write \"*.md\" \"examples/**/*.md\"",