auklet 0.1.3 → 0.1.5

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 (72) hide show
  1. package/README.md +113 -412
  2. package/dist/build/tsdown/dependencies.js +2 -2
  3. package/dist/cli/build.d.ts +3 -5
  4. package/dist/cli/build.js +88 -17
  5. package/dist/cli/buildCss.d.ts +10 -3
  6. package/dist/cli/buildCss.js +40 -29
  7. package/dist/cli/buildWorkspace.d.ts +23 -0
  8. package/dist/cli/buildWorkspace.js +43 -0
  9. package/dist/cli/dev.d.ts +2 -1
  10. package/dist/cli/dev.js +131 -16
  11. package/dist/cli/main.js +36 -12
  12. package/dist/cli/parse/build.d.ts +62 -0
  13. package/dist/cli/parse/build.js +161 -0
  14. package/dist/cli/parse/core.d.ts +14 -0
  15. package/dist/cli/parse/core.js +68 -0
  16. package/dist/cli/parse/dev.d.ts +17 -0
  17. package/dist/cli/parse/dev.js +4 -0
  18. package/dist/cli/parse/owner.d.ts +11 -0
  19. package/dist/cli/parse/owner.js +25 -0
  20. package/dist/cli/parse/publish.d.ts +19 -0
  21. package/dist/cli/parse/publish.js +60 -0
  22. package/dist/cli/parse/values.d.ts +17 -0
  23. package/dist/cli/parse/values.js +14 -0
  24. package/dist/cli/parse/workspace.d.ts +12 -0
  25. package/dist/cli/parse/workspace.js +45 -0
  26. package/dist/css/core/style/dependencies.d.ts +0 -1
  27. package/dist/css/core/style/dependencies.js +0 -3
  28. package/dist/css/core/style/entries.js +2 -2
  29. package/dist/css/core/style/files.d.ts +0 -1
  30. package/dist/css/core/style/files.js +0 -3
  31. package/dist/css/core/stylePackageContext.js +3 -3
  32. package/dist/css/inspect.js +4 -3
  33. package/dist/css/vite/hmr.js +2 -2
  34. package/dist/css/vite/moduleGraph/packageSource/monorepo.d.ts +1 -1
  35. package/dist/css/vite/moduleGraph/packageSource/monorepo.js +2 -2
  36. package/dist/env.d.ts +22 -0
  37. package/dist/env.js +105 -0
  38. package/dist/logger.d.ts +0 -1
  39. package/dist/logger.js +0 -3
  40. package/dist/publish/api/npmrc.d.ts +1 -1
  41. package/dist/publish/api/npmrc.js +1 -4
  42. package/dist/publish/api/pnpmApi.d.ts +5 -13
  43. package/dist/publish/api/pnpmApi.js +5 -47
  44. package/dist/publish/api/pnpmPublishApi.d.ts +2 -2
  45. package/dist/publish/api/pnpmPublishApi.js +5 -3
  46. package/dist/publish/cli.d.ts +0 -12
  47. package/dist/publish/cli.js +27 -106
  48. package/dist/publish/inspect.js +19 -9
  49. package/dist/publish/inspectPack.js +6 -2
  50. package/dist/publish/inspectRegistry.d.ts +3 -2
  51. package/dist/publish/inspectRegistry.js +11 -4
  52. package/dist/publish/publishEnv.d.ts +13 -0
  53. package/dist/publish/publishEnv.js +21 -0
  54. package/dist/publish/publishRunner.d.ts +3 -2
  55. package/dist/publish/publishRunner.js +9 -7
  56. package/dist/publish/runner/packageBuilder.d.ts +2 -3
  57. package/dist/publish/runner/packageBuilder.js +5 -3
  58. package/dist/publish/runner/packagePublisher.d.ts +3 -2
  59. package/dist/publish/runner/packagePublisher.js +4 -2
  60. package/dist/publish/runner/publishPreflight.d.ts +3 -2
  61. package/dist/publish/runner/publishPreflight.js +13 -6
  62. package/dist/publish/runner/versionWriter.d.ts +1 -1
  63. package/dist/publish/targetResolver.d.ts +2 -2
  64. package/dist/publish/targetResolver.js +34 -75
  65. package/dist/publish/types.d.ts +6 -7
  66. package/dist/workspace/targets.d.ts +31 -0
  67. package/dist/workspace/targets.js +144 -0
  68. package/package.json +1 -1
  69. package/dist/cli/buildArgs.d.ts +0 -8
  70. package/dist/cli/buildArgs.js +0 -114
  71. package/dist/cli/publish.d.ts +0 -2
  72. package/dist/cli/publish.js +0 -9
package/dist/env.js ADDED
@@ -0,0 +1,105 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { parseEnv } from 'node:util';
4
+ import { findWorkspaceRoot } from '#auklet/workspace/root';
5
+ const envFileNames = ['.env', '.env.local'];
6
+ export class AukletEnvContext {
7
+ packageRoot;
8
+ root;
9
+ env;
10
+ processEnv;
11
+ constructor(packageRoot, root, options = {}) {
12
+ this.packageRoot = packageRoot;
13
+ this.root = root;
14
+ this.processEnv = { ...(options.processEnv ?? process.env) };
15
+ this.env = this.createProcessEnvOverrides(this.readEnv());
16
+ }
17
+ get values() {
18
+ return this.env;
19
+ }
20
+ get normalizedValues() {
21
+ return Object.keys(this.values).length ? this.values : undefined;
22
+ }
23
+ createPackageContext(packageRoot) {
24
+ return new AukletEnvContext(packageRoot, this.root, {
25
+ processEnv: this.processEnv,
26
+ });
27
+ }
28
+ resolveValue(value, options) {
29
+ if (!value)
30
+ return undefined;
31
+ if (!value.startsWith('env:'))
32
+ return value;
33
+ const name = value.slice('env:'.length);
34
+ if (!name) {
35
+ throw new Error(`${options.label} env: requires an environment name.`);
36
+ }
37
+ const resolved = this.processEnv[name] ?? this.values[name];
38
+ if (!resolved) {
39
+ throw new Error(`${options.label} environment is missing: ${name}`);
40
+ }
41
+ return resolved;
42
+ }
43
+ resolveBoolean(value, options) {
44
+ if (value === undefined)
45
+ return false;
46
+ if (typeof value === 'boolean')
47
+ return value;
48
+ if (!value)
49
+ return true;
50
+ const resolved = this.resolveValue(value, options);
51
+ if (resolved === undefined || !resolved)
52
+ return true;
53
+ const normalized = resolved.toLowerCase();
54
+ if (['1', 'true', 'yes', 'on'].includes(normalized))
55
+ return true;
56
+ if (['0', 'false', 'no', 'off'].includes(normalized))
57
+ return false;
58
+ throw new Error(`${options.label} requires a boolean value.`);
59
+ }
60
+ async run(fn) {
61
+ const originalEnv = { ...process.env };
62
+ for (const [key, value] of Object.entries(this.values)) {
63
+ if (originalEnv[key] === undefined && value !== undefined) {
64
+ process.env[key] = value;
65
+ }
66
+ }
67
+ try {
68
+ return await fn();
69
+ }
70
+ finally {
71
+ process.env = originalEnv;
72
+ }
73
+ }
74
+ readEnv() {
75
+ const env = {};
76
+ for (const file of this.findEnvFiles()) {
77
+ Object.assign(env, parseEnv(fs.readFileSync(file, 'utf8')));
78
+ }
79
+ return env;
80
+ }
81
+ findEnvFiles() {
82
+ const files = [];
83
+ const packageDir = path.resolve(this.packageRoot);
84
+ const rootDir = path.resolve(this.root ?? findWorkspaceRoot(packageDir) ?? packageDir);
85
+ // Files are read in order and later files override earlier ones.
86
+ // Final priority is process.env > package .env.local > package .env >
87
+ // root .env.local > root .env.
88
+ const rootEnvFiles = envFileNames.map((fileName) => path.join(rootDir, fileName));
89
+ const packageEnvFiles = envFileNames.map((fileName) => path.join(packageDir, fileName));
90
+ for (const file of rootEnvFiles) {
91
+ if (fs.existsSync(file)) {
92
+ files.push(file);
93
+ }
94
+ }
95
+ for (const file of packageEnvFiles) {
96
+ if (!files.includes(file) && fs.existsSync(file)) {
97
+ files.push(file);
98
+ }
99
+ }
100
+ return files;
101
+ }
102
+ createProcessEnvOverrides(env) {
103
+ return Object.fromEntries(Object.entries(env).filter(([key]) => this.processEnv[key] === undefined));
104
+ }
105
+ }
package/dist/logger.d.ts CHANGED
@@ -2,4 +2,3 @@ import { Logger, type LoggerOptions } from 'briefing';
2
2
  export type AukletLogger = Logger;
3
3
  export type CreateAukletLoggerOptions = Pick<LoggerOptions, 'scope' | 'prefix' | 'colors' | 'silent' | 'verbose' | 'sink'>;
4
4
  export declare function createAukletLogger(options?: CreateAukletLoggerOptions): Logger;
5
- export declare function createScopedAukletLogger(scope: string): Logger;
package/dist/logger.js CHANGED
@@ -9,6 +9,3 @@ export function createAukletLogger(options = {}) {
9
9
  sink: options.sink,
10
10
  });
11
11
  }
12
- export function createScopedAukletLogger(scope) {
13
- return createAukletLogger({ scope });
14
- }
@@ -1,5 +1,5 @@
1
1
  export type NpmrcAuthEnvOptions = {
2
- token?: string;
2
+ env?: Record<string, string | undefined>;
3
3
  };
4
4
  export declare function findNpmrcWithAuthToken(packageRoot: string, root: string, registry?: string): string | undefined;
5
5
  export declare function findNpmrcFiles(packageRoot: string, root: string): string[];
@@ -79,11 +79,8 @@ const getNpmrcAuthLines = (content) => {
79
79
  line.includes('_authToken'));
80
80
  };
81
81
  const createAvailableAuthEnv = (options) => {
82
- if (!options.token)
83
- return process.env;
84
82
  return {
85
83
  ...process.env,
86
- NODE_AUTH_TOKEN: options.token,
87
- NPM_TOKEN: options.token,
84
+ ...options.env,
88
85
  };
89
86
  };
@@ -1,5 +1,4 @@
1
1
  import { execa, type Options } from 'execa';
2
- import type { WorkspacePackage } from '#auklet/publish/types';
3
2
  export declare class NpmPublishAuthenticationError extends Error {
4
3
  readonly packageRoot: string;
5
4
  constructor(packageRoot: string);
@@ -9,36 +8,29 @@ export declare class NpmPackageVersionExistsError extends Error {
9
8
  }
10
9
  export declare function withPnpmTimeout(subprocess: ReturnType<typeof execa>, timeout: number): Promise<import("node_modules/execa/types/return/result").CommonResult<false, Options> & import("node_modules/execa/types/return/result").OmitErrorIfReject<boolean | undefined>>;
11
10
  export declare function ensurePnpm(options?: {
12
- token?: string;
11
+ env?: Record<string, string | undefined>;
13
12
  }): Promise<string>;
14
- export declare function readPnpmWorkspacePackages(root: string, options?: {
15
- token?: string;
16
- }): Promise<WorkspacePackage[]>;
17
13
  export declare function runPnpmBuild(packageRoot: string, options?: {
18
- token?: string;
14
+ env?: Record<string, string | undefined>;
19
15
  }): Promise<void>;
20
16
  export declare function runPnpmPublish(packageRoot: string, args: Array<string>, options?: {
21
- token?: string;
17
+ env?: Record<string, string | undefined>;
22
18
  }): Promise<void>;
23
19
  export declare function runPnpmWhoami(packageRoot: string, options?: {
24
20
  packageName?: string;
25
21
  registry?: string;
26
22
  timeout?: number;
27
- token?: string;
23
+ env?: Record<string, string | undefined>;
28
24
  }): Promise<string>;
29
25
  export declare function hasPublishedPackageVersion(packageRoot: string, packageName: string, version: string, options?: {
30
26
  registry?: string;
31
27
  timeout?: number;
32
- token?: string;
28
+ env?: Record<string, string | undefined>;
33
29
  }): Promise<boolean>;
34
30
  export declare function runPnpmOwnerAdd(packageName: string, user: string, options: {
35
31
  cwd: string;
36
32
  otp?: string;
37
33
  }): Promise<void>;
38
- export declare function createPnpmAuthEnv(token?: string): {
39
- NODE_AUTH_TOKEN: string;
40
- NPM_TOKEN: string;
41
- } | undefined;
42
34
  export declare function hasNpmAuthChallenge(result: {
43
35
  stdout?: unknown;
44
36
  stderr?: unknown;
@@ -1,7 +1,5 @@
1
- import { isPlainObject, isString } from 'aidly';
2
1
  import { execa } from 'execa';
3
2
  import semver from 'semver';
4
- import { readPnpmWorkspacePackageInfo } from '#auklet/workspace/packages';
5
3
  const supportedPnpmRange = '>=10.0.0';
6
4
  export class NpmPublishAuthenticationError extends Error {
7
5
  packageRoot;
@@ -52,7 +50,7 @@ export async function withPnpmTimeout(subprocess, timeout) {
52
50
  }
53
51
  export async function ensurePnpm(options = {}) {
54
52
  const result = await runPnpm(['--version'], {
55
- env: createPnpmAuthEnv(options.token),
53
+ env: options.env,
56
54
  });
57
55
  const stdout = String(result.stdout ?? '');
58
56
  if (hasFailedPnpmResult(result) || !stdout) {
@@ -68,26 +66,10 @@ export async function ensurePnpm(options = {}) {
68
66
  }
69
67
  return version;
70
68
  }
71
- export async function readPnpmWorkspacePackages(root, options = {}) {
72
- try {
73
- return (await readPnpmWorkspacePackageInfo(root, {
74
- env: createPnpmAuthEnv(options.token),
75
- })).map((item) => {
76
- if (!isWorkspacePackage(item))
77
- throwInvalidWorkspacePackages();
78
- return item;
79
- });
80
- }
81
- catch (error) {
82
- throw new Error('[publish] failed to read pnpm workspace packages.', {
83
- cause: error,
84
- });
85
- }
86
- }
87
69
  export async function runPnpmBuild(packageRoot, options = {}) {
88
70
  const result = await runPnpm(['run', 'build'], {
89
71
  cwd: packageRoot,
90
- env: createPnpmAuthEnv(options.token),
72
+ env: options.env,
91
73
  stdio: 'inherit',
92
74
  });
93
75
  if (hasFailedPnpmResult(result)) {
@@ -98,7 +80,7 @@ export async function runPnpmPublish(packageRoot, args, options = {}) {
98
80
  const isDryRun = args.includes('--dry-run');
99
81
  const result = await runPnpm(['publish', ...args], {
100
82
  cwd: packageRoot,
101
- env: createPnpmAuthEnv(options.token),
83
+ env: options.env,
102
84
  stdio: isDryRun ? 'pipe' : 'inherit',
103
85
  });
104
86
  if (isDryRun)
@@ -116,7 +98,7 @@ export async function runPnpmWhoami(packageRoot, options = {}) {
116
98
  args.push('--registry', options.registry);
117
99
  const result = await runPnpm(args, {
118
100
  cwd: packageRoot,
119
- env: createPnpmAuthEnv(options.token),
101
+ env: options.env,
120
102
  timeout: options.timeout,
121
103
  });
122
104
  if (hasFailedPnpmResult(result)) {
@@ -135,7 +117,7 @@ export async function hasPublishedPackageVersion(packageRoot, packageName, versi
135
117
  args.push('--registry', options.registry);
136
118
  const result = await runPnpm(args, {
137
119
  cwd: packageRoot,
138
- env: createPnpmAuthEnv(options.token),
120
+ env: options.env,
139
121
  timeout: options.timeout,
140
122
  });
141
123
  if (!hasFailedPnpmResult(result)) {
@@ -159,26 +141,6 @@ export async function runPnpmOwnerAdd(packageName, user, options) {
159
141
  throw new Error(`[publish] pnpm owner add failed for ${user} -> ${packageName}.`);
160
142
  }
161
143
  }
162
- export function createPnpmAuthEnv(token) {
163
- if (!token)
164
- return undefined;
165
- return {
166
- NODE_AUTH_TOKEN: token,
167
- NPM_TOKEN: token,
168
- };
169
- }
170
- const isWorkspacePackage = (value) => {
171
- if (!isPlainObject(value)) {
172
- return false;
173
- }
174
- return (isString(value.name) &&
175
- value.name.length > 0 &&
176
- isString(value.path) &&
177
- value.path.length > 0 &&
178
- isString(value.version) &&
179
- value.version.length > 0 &&
180
- (value.private === undefined || typeof value.private === 'boolean'));
181
- };
182
144
  const hasFailedPnpmResult = (result) => {
183
145
  return result.failed === true || result.exitCode !== 0;
184
146
  };
@@ -189,10 +151,6 @@ const getPnpmFailureReason = (result) => {
189
151
  const stdout = String(result.stdout ?? '').trim();
190
152
  return stdout || null;
191
153
  };
192
- function throwInvalidWorkspacePackages() {
193
- throw new Error('[publish] failed to read pnpm workspace packages.\n' +
194
- '[publish] Expected `pnpm list -r --depth -1 --json` to return package objects with name/path/version.');
195
- }
196
154
  export function hasNpmAuthChallenge(result) {
197
155
  const output = [result.stdout, result.stderr]
198
156
  .map((value) => String(value ?? ''))
@@ -1,4 +1,4 @@
1
- import type { PublishOptions, PublishTarget } from '#auklet/publish/types';
1
+ import type { PublishOptions, PublishRuntime, PublishTarget } from '#auklet/publish/types';
2
2
  export declare class PnpmPublishApi {
3
- publish(target: PublishTarget, options: PublishOptions): Promise<void>;
3
+ publish(target: PublishTarget, options: PublishOptions, runtime: PublishRuntime): Promise<void>;
4
4
  }
@@ -1,10 +1,12 @@
1
1
  import { runPnpmPublish } from '#auklet/publish/api/pnpmApi';
2
2
  import { createPublishArgs } from '#auklet/publish/api/publishArgs';
3
+ import { createPublishTargetEnv } from '#auklet/publish/publishEnv';
3
4
  export class PnpmPublishApi {
4
- async publish(target, options) {
5
+ async publish(target, options, runtime) {
5
6
  const args = createPublishArgs(target, options);
6
- if (options.token) {
7
- await runPnpmPublish(target.packageRoot, args, { token: options.token });
7
+ const { env } = createPublishTargetEnv(options, runtime, target);
8
+ if (env) {
9
+ await runPnpmPublish(target.packageRoot, args, { env });
8
10
  return;
9
11
  }
10
12
  await runPnpmPublish(target.packageRoot, args);
@@ -1,14 +1,2 @@
1
1
  export declare function runPublishCli(args: Array<string>): Promise<void>;
2
- export declare function resolvePublishCliOptions(args: Array<string>, cwd?: string): {
3
- cwd: string;
4
- otp: string | undefined;
5
- filters: string[];
6
- version: string | undefined;
7
- git: boolean;
8
- format: boolean;
9
- dryRun: boolean;
10
- allowDirty: boolean;
11
- ignoreScripts: boolean;
12
- token: string | undefined;
13
- };
14
2
  export declare function runOwnerCli(args: Array<string>): Promise<void>;
@@ -1,116 +1,37 @@
1
- import minimist from 'minimist';
2
- import { isArray } from 'aidly';
1
+ import { AukletEnvContext } from '#auklet/env';
2
+ import { ensurePnpm } from '#auklet/publish/api/pnpmApi';
3
3
  import { OwnerRunner } from '#auklet/publish/ownerRunner';
4
4
  import { PublishRunner } from '#auklet/publish/publishRunner';
5
5
  import { validateNpmrcAuthEnv } from '#auklet/publish/api/npmrc';
6
- import { ensurePnpm } from '#auklet/publish/api/pnpmApi';
6
+ import { createPublishRootEnv } from '#auklet/publish/publishEnv';
7
7
  import { findWorkspaceRoot } from '#auklet/workspace/root';
8
- const publishFlags = new Set([
9
- '_',
10
- 'filter',
11
- 'version',
12
- 'dry-run',
13
- 'format',
14
- 'git',
15
- 'otp',
16
- 'token',
17
- 'ignore-scripts',
18
- 'allow-dirty',
19
- ]);
20
- const ownerFlags = new Set(['_', 'filter', 'package', 'otp']);
8
+ import { parseOwnerCommand } from '#auklet/cli/parse/owner';
9
+ import { parsePublishCommand } from '#auklet/cli/parse/publish';
21
10
  export async function runPublishCli(args) {
22
- const options = resolvePublishCliOptions(args);
23
- validatePublishCliNpmrcAuthEnv(options.cwd, options.token);
24
- await ensurePnpm({ token: options.token });
25
- await new PublishRunner(options).run();
26
- }
27
- export function resolvePublishCliOptions(args, cwd = process.cwd()) {
28
- const argv = parsePublishArgs(args);
29
- if (argv._.length) {
30
- throw new Error(`[publish] unknown publish argument: ${argv._.join(' ')}`);
31
- }
32
- return {
33
- cwd,
34
- otp: stringOption(argv.otp),
35
- filters: toArray(argv.filter),
36
- version: stringOption(argv.version),
37
- git: argv.git !== false,
38
- format: argv.format !== false,
39
- dryRun: argv['dry-run'] === true,
40
- allowDirty: argv['allow-dirty'] === true,
41
- ignoreScripts: argv['ignore-scripts'] === true,
42
- token: stringOption(argv.token),
43
- };
44
- }
45
- const parsePublishArgs = (args) => {
46
- const cliArgs = stripLeadingArgsSeparator(args);
47
- validateNoPrefixedFlags(cliArgs, new Set(['--no-format', '--no-git']));
48
- const argv = minimist(cliArgs, {
49
- string: ['filter', 'version', 'otp', 'token'],
50
- boolean: ['dry-run', 'format', 'git', 'ignore-scripts', 'allow-dirty'],
51
- default: {
52
- git: true,
53
- format: true,
54
- },
11
+ const cwd = process.cwd();
12
+ const root = findWorkspaceRoot(cwd) ?? cwd;
13
+ const envContext = new AukletEnvContext(cwd, root);
14
+ await envContext.run(async () => {
15
+ const runtime = { envContext };
16
+ const options = parsePublishCommand(args, { cwd, envContext });
17
+ const { env } = createPublishRootEnv(options, runtime);
18
+ validatePublishCliNpmrcAuthEnv(options.cwd, env);
19
+ await ensurePnpm({ env });
20
+ await new PublishRunner(options, runtime).run();
55
21
  });
56
- validateFlags(argv, publishFlags);
57
- return argv;
58
- };
22
+ }
59
23
  export async function runOwnerCli(args) {
60
- const cliArgs = stripLeadingArgsSeparator(args);
61
- validateNoPrefixedFlags(cliArgs, new Set());
62
- const argv = minimist(cliArgs, {
63
- string: ['filter', 'package', 'otp'],
64
- });
65
- validateFlags(argv, ownerFlags);
66
- const [subcommand, ...users] = argv._;
67
- if (subcommand !== 'add') {
68
- throw new Error('[publish] expected owner command: auk owner add <user...>');
69
- }
70
- if (!users.length) {
71
- throw new Error('[publish] owner add requires at least one user.');
72
- }
73
24
  const cwd = process.cwd();
74
- validatePublishCliNpmrcAuthEnv(cwd);
75
- await ensurePnpm();
76
- await new OwnerRunner({
77
- cwd,
78
- users,
79
- filters: toArray(argv.filter),
80
- packages: toArray(argv.package),
81
- otp: stringOption(argv.otp),
82
- }).run();
25
+ const root = findWorkspaceRoot(cwd) ?? cwd;
26
+ const envContext = new AukletEnvContext(cwd, root);
27
+ await envContext.run(async () => {
28
+ const options = parseOwnerCommand(args, { cwd, envContext });
29
+ const env = envContext.values;
30
+ validatePublishCliNpmrcAuthEnv(cwd, env);
31
+ await ensurePnpm({ env: envContext.normalizedValues });
32
+ await new OwnerRunner(options).run();
33
+ });
83
34
  }
84
- const validateFlags = (argv, allowedFlags) => {
85
- for (const flag of Object.keys(argv)) {
86
- if (!allowedFlags.has(flag)) {
87
- throw new Error(`[publish] unknown option: --${flag}`);
88
- }
89
- }
90
- };
91
- const validateNoPrefixedFlags = (args, allowedFlags) => {
92
- const flag = args.find((arg) => arg.startsWith('--no-') && !allowedFlags.has(arg));
93
- if (flag) {
94
- throw new Error(`[publish] unknown option: ${flag}`);
95
- }
96
- };
97
- const stripLeadingArgsSeparator = (args) => {
98
- return args.filter((arg) => arg !== '--');
99
- };
100
- const toArray = (value) => {
101
- if (value === undefined)
102
- return [];
103
- return isArray(value)
104
- ? value.map(String).filter(Boolean)
105
- : [String(value)].filter(Boolean);
106
- };
107
- const stringOption = (value) => {
108
- if (value === undefined)
109
- return undefined;
110
- if (isArray(value))
111
- return String(value.at(-1));
112
- return String(value);
113
- };
114
- const validatePublishCliNpmrcAuthEnv = (cwd, token) => {
115
- validateNpmrcAuthEnv(cwd, findWorkspaceRoot(cwd) ?? cwd, { token });
35
+ const validatePublishCliNpmrcAuthEnv = (cwd, env) => {
36
+ validateNpmrcAuthEnv(cwd, findWorkspaceRoot(cwd) ?? cwd, { env });
116
37
  };
@@ -1,23 +1,32 @@
1
1
  import path from 'node:path';
2
2
  import { isString } from 'aidly';
3
+ import { AukletEnvContext } from '#auklet/env';
3
4
  import { createAukletLogger } from '#auklet/logger';
4
- import { resolvePublishTag } from '#auklet/publish/api/publishArgs';
5
- import { getPublishRegistry } from '#auklet/publish/api/registry';
5
+ import { findWorkspaceRoot } from '#auklet/workspace/root';
6
6
  import { ensurePnpm } from '#auklet/publish/api/pnpmApi';
7
+ import { getPublishRegistry } from '#auklet/publish/api/registry';
8
+ import { resolvePublishTag } from '#auklet/publish/api/publishArgs';
9
+ import { parsePublishCommand } from '#auklet/cli/parse/publish';
7
10
  import { validateNpmrcAuthEnv } from '#auklet/publish/api/npmrc';
8
- import { resolvePublishCliOptions } from '#auklet/publish/cli';
9
- import { findWorkspaceRoot } from '#auklet/workspace/root';
11
+ import { createPublishRootEnv } from '#auklet/publish/publishEnv';
10
12
  import { inspectPublishRegistry, } from '#auklet/publish/inspectRegistry';
11
13
  import { inspectPackageFiles, PackInspectReporter, } from '#auklet/publish/inspectPack';
12
14
  import { resolvePublishPlan } from '#auklet/publish/targetResolver';
13
15
  export async function runInspectPublishCli(args) {
14
- const options = resolvePublishCliOptions(args);
15
- validateNpmrcAuthEnv(options.cwd, findWorkspaceRoot(options.cwd) ?? options.cwd, {
16
- token: options.token,
16
+ const cwd = process.cwd();
17
+ const root = findWorkspaceRoot(cwd) ?? cwd;
18
+ const envContext = new AukletEnvContext(cwd, root);
19
+ return envContext.run(async () => {
20
+ const options = parsePublishCommand(args, { cwd, envContext });
21
+ return runInspectPublish(options, root, { envContext });
17
22
  });
18
- await ensurePnpm({ token: options.token });
23
+ }
24
+ async function runInspectPublish(options, root, runtime) {
25
+ const { env } = createPublishRootEnv(options, runtime);
26
+ validateNpmrcAuthEnv(options.cwd, root, { env });
27
+ await ensurePnpm({ env });
19
28
  const logger = createAukletLogger({ scope: 'inspect' });
20
- const plan = await resolvePublishPlan(options, logger);
29
+ const plan = await resolvePublishPlan(options, runtime, logger);
21
30
  const packageFileChecks = inspectPackageFiles(plan.targets);
22
31
  const packageFileCheckFailed = packageFileChecks.some((check) => check.status === 'missing');
23
32
  if (packageFileCheckFailed) {
@@ -28,6 +37,7 @@ export async function runInspectPublishCli(args) {
28
37
  spinner.start();
29
38
  const registryChecks = await inspectPublishRegistry(plan, {
30
39
  token: options.token,
40
+ runtime,
31
41
  onCheck: (info) => {
32
42
  spinner.text([
33
43
  'Checking registry ',
@@ -1,17 +1,21 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { isArray, isPlainObject, isString } from 'aidly';
4
+ import { AukletEnvContext } from '#auklet/env';
4
5
  import { createAukletLogger } from '#auklet/logger';
6
+ import { findWorkspaceRoot } from '#auklet/workspace/root';
5
7
  import { resolvePublishPlan } from '#auklet/publish/targetResolver';
6
8
  export async function runInspectPackCli(args) {
7
9
  const options = resolveInspectPackOptions(args);
10
+ const root = findWorkspaceRoot(options.cwd) ?? options.cwd;
11
+ const envContext = new AukletEnvContext(options.cwd, root);
8
12
  const logger = createAukletLogger({ scope: 'inspect' });
9
- const plan = await resolvePublishPlan({
13
+ const plan = await envContext.run(() => resolvePublishPlan({
10
14
  cwd: options.cwd,
11
15
  filters: options.filters,
12
16
  dryRun: true,
13
17
  version: undefined,
14
- }, logger);
18
+ }, { envContext }, logger));
15
19
  const checks = inspectPackageFiles(plan.targets);
16
20
  new PackInspectReporter(options.cwd, plan.targets, checks).report();
17
21
  return checks.some((check) => check.status === 'missing') ? 1 : 0;
@@ -1,4 +1,4 @@
1
- import type { PublishOptions, PublishPlan } from '#auklet/publish/types';
1
+ import type { PublishOptions, PublishPlan, PublishRuntime } from '#auklet/publish/types';
2
2
  export type PublishRegistryCheckStatus = 'success' | 'error';
3
3
  export type PublishRegistryCheck = {
4
4
  packageName: string;
@@ -18,7 +18,8 @@ export type PublishRegistryRetryInfo = {
18
18
  export type PublishRegistryCheckInfo = Pick<PublishRegistryRetryInfo, 'packageName' | 'registry' | 'check'>;
19
19
  export type InspectPublishRegistryOptions = {
20
20
  token?: PublishOptions['token'];
21
+ runtime: PublishRuntime;
21
22
  onCheck?: (info: PublishRegistryCheckInfo) => void;
22
23
  onRetry?: (info: PublishRegistryRetryInfo) => void;
23
24
  };
24
- export declare function inspectPublishRegistry(plan: PublishPlan, options?: InspectPublishRegistryOptions): Promise<PublishRegistryCheck[]>;
25
+ export declare function inspectPublishRegistry(plan: PublishPlan, options: InspectPublishRegistryOptions): Promise<PublishRegistryCheck[]>;
@@ -1,9 +1,10 @@
1
1
  import { retry } from 'aidly';
2
2
  import { getPublishRegistry } from '#auklet/publish/api/registry';
3
- import { hasPublishedPackageVersion, runPnpmWhoami, } from '#auklet/publish/api/pnpmApi';
3
+ import { runPnpmWhoami, hasPublishedPackageVersion, } from '#auklet/publish/api/pnpmApi';
4
+ import { createPublishTargetEnv } from '#auklet/publish/publishEnv';
4
5
  const registryCheckTimeout = 5_000;
5
6
  const registryCheckRetryTimes = 2;
6
- export async function inspectPublishRegistry(plan, options = {}) {
7
+ export async function inspectPublishRegistry(plan, options) {
7
8
  const authResults = new Map();
8
9
  const checks = [];
9
10
  for (const target of plan.targets) {
@@ -26,6 +27,9 @@ export async function inspectPublishRegistry(plan, options = {}) {
26
27
  return checks;
27
28
  }
28
29
  const checkAuth = async (authResults, authKey, packageRoot, packageName, registry, options) => {
30
+ const { env } = createPublishTargetEnv(options, options.runtime, {
31
+ packageRoot,
32
+ });
29
33
  try {
30
34
  options.onCheck?.({
31
35
  packageName,
@@ -35,7 +39,7 @@ const checkAuth = async (authResults, authKey, packageRoot, packageName, registr
35
39
  await retryWithLog(() => runPnpmWhoami(packageRoot, {
36
40
  packageName,
37
41
  registry,
38
- token: options.token,
42
+ env,
39
43
  timeout: registryCheckTimeout,
40
44
  }), {
41
45
  check: 'auth',
@@ -53,6 +57,9 @@ const checkAuth = async (authResults, authKey, packageRoot, packageName, registr
53
57
  }
54
58
  };
55
59
  const checkVersion = async (packageRoot, packageName, version, registry, options) => {
60
+ const { env } = createPublishTargetEnv(options, options.runtime, {
61
+ packageRoot,
62
+ });
56
63
  try {
57
64
  options.onCheck?.({
58
65
  packageName,
@@ -61,7 +68,7 @@ const checkVersion = async (packageRoot, packageName, version, registry, options
61
68
  });
62
69
  const exists = await retryWithLog(() => hasPublishedPackageVersion(packageRoot, packageName, version, {
63
70
  registry,
64
- token: options.token,
71
+ env,
65
72
  timeout: registryCheckTimeout,
66
73
  }), {
67
74
  check: 'version',
@@ -0,0 +1,13 @@
1
+ import type { PublishOptions, PublishRuntime, PublishTarget } from '#auklet/publish/types';
2
+ export type PublishPnpmEnv = {
3
+ env?: Record<string, string | undefined>;
4
+ token?: string;
5
+ };
6
+ export declare function createPublishRootEnv(options: Pick<PublishOptions, 'token'>, runtime: PublishRuntime): {
7
+ env: Record<string, string | undefined> | undefined;
8
+ token: string | undefined;
9
+ };
10
+ export declare function createPublishTargetEnv(options: Pick<PublishOptions, 'token'>, runtime: PublishRuntime, target: Pick<PublishTarget, 'packageRoot'>): {
11
+ env: Record<string, string | undefined> | undefined;
12
+ token: string | undefined;
13
+ };
@@ -0,0 +1,21 @@
1
+ export function createPublishRootEnv(options, runtime) {
2
+ return createPublishPnpmEnv(options.token, runtime.envContext);
3
+ }
4
+ export function createPublishTargetEnv(options, runtime, target) {
5
+ const envContext = runtime.envContext.createPackageContext(target.packageRoot);
6
+ return createPublishPnpmEnv(options.token, envContext);
7
+ }
8
+ const createPublishPnpmEnv = (token, envContext) => {
9
+ const resolvedToken = token?.resolve(envContext);
10
+ const resolvedEnv = resolvedToken
11
+ ? {
12
+ ...envContext.values,
13
+ NODE_AUTH_TOKEN: resolvedToken,
14
+ NPM_TOKEN: resolvedToken,
15
+ }
16
+ : envContext.values;
17
+ return {
18
+ env: Object.keys(resolvedEnv).length ? resolvedEnv : undefined,
19
+ token: resolvedToken,
20
+ };
21
+ };