Add release pipeline and upgrade toolchain to TypeScript 7
Publish snapshot / snapshot (push) Failing after 1m58s
Publish snapshot / snapshot (push) Failing after 1m58s
Publishing infrastructure - Three Gitea workflows: ci.yml (PRs, non-main pushes), publish-snapshot.yml (main -> Gitea under dist-tag @main) and release.yml (tags -> Gitea + npmjs) - Tag-driven releases as <package-dir>-v<version>; the manifest stays the source of truth and release.yml refuses to run if tag and manifest disagree - Every publish is idempotent: each step checks the registry first, so a run that fails on the second registry can simply be re-run - Hard coverage gate (85% branches) shared by CI, the pre-push hook and local runs, since the thresholds live in vitest.config.ts rather than a CI flag - README.PUBLISH.md documents the whole mechanism Toolchain - TypeScript 7 native compiler; drop tsgo and ts-node, use tsx for dev runs - Biome 1.9 -> 2.x, Vitest 1 -> 4, zod 3 -> 4, inquirer 8 -> 14, pnpm 11.17.0 - Replace inquirer-checkbox-plus-prompt, which is peer-capped at inquirer <9, with enquirer's AutoComplete; the CubeSelection contract is unchanged - Stand in for zod 4's removed z.AnyZodObject with a local AnyObjectSchema Repo hygiene - Stop tracking dist/; ignore coverage/, *.tsbuildinfo, .npmrc* and release.json - Drop package-lock.json in favour of pnpm-lock.yaml Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,8 +8,8 @@ import type { Variables } from '../nopy.common.js';
|
||||
import type { NopyConfig } from '../nopy.config.js';
|
||||
import type { DeployCall } from '../nopy.executor.js';
|
||||
import { VariableAssignment } from '../nopy.prompts.js';
|
||||
import { type CubeSession, type NopySession } from '../nopy.session.js';
|
||||
import type { Cube, CubeVariables, DependencySpec, HookContext } from './types.js';
|
||||
import type { CubeSession, NopySession } from '../nopy.session.js';
|
||||
import type { Cube, CubeVariables, HookContext } from './types.js';
|
||||
|
||||
const log = getLogger(['nopy', 'resolution']);
|
||||
|
||||
@@ -40,7 +40,11 @@ export class BuildContext {
|
||||
/**
|
||||
* Resolves a cube, its dependencies, and hooks recursively
|
||||
*/
|
||||
public async resolveCube(cubeId: string, host: string, overrides: CubeVariables = {}): Promise<void> {
|
||||
public async resolveCube(
|
||||
cubeId: string,
|
||||
host: string,
|
||||
overrides: CubeVariables = {}
|
||||
): Promise<void> {
|
||||
const cube = this.allCubes[cubeId];
|
||||
if (!cube) {
|
||||
throw new Error(`Cube not found: ${cubeId}`);
|
||||
@@ -56,7 +60,7 @@ export class BuildContext {
|
||||
|
||||
// 2. Variable collection
|
||||
if (this.options.isSessionReplay) {
|
||||
const sessionCube = this.session.cubes.find(c => c.key === cubeId);
|
||||
const sessionCube = this.session.cubes.find((c) => c.key === cubeId);
|
||||
if (sessionCube) {
|
||||
this.variables.assign(cubeId, 'defaults', sessionCube.variables);
|
||||
}
|
||||
@@ -101,7 +105,7 @@ export class BuildContext {
|
||||
private buildDeployCall(cube: Cube, host: string): void {
|
||||
const cubeId = cube.id;
|
||||
const callKey = `${cubeId}:${host}`;
|
||||
|
||||
|
||||
if (this.resolvedCubes.has(callKey)) return;
|
||||
|
||||
const parts: string[] = [];
|
||||
@@ -128,7 +132,7 @@ export class BuildContext {
|
||||
dependencies: [],
|
||||
});
|
||||
|
||||
if (!this.cubeSessions.some(s => s.key === cubeId)) {
|
||||
if (!this.cubeSessions.some((s) => s.key === cubeId)) {
|
||||
this.cubeSessions.push({
|
||||
key: cubeId,
|
||||
variables: this.variables.get(cubeId, 'prompts'),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @module cubes/factories
|
||||
*/
|
||||
|
||||
import { Manifest } from './types.js';
|
||||
import { type AnyObjectSchema, Manifest } from './types.js';
|
||||
|
||||
/**
|
||||
* Creates a manifest configuration for a cube
|
||||
@@ -11,7 +11,7 @@ import { Manifest } from './types.js';
|
||||
* @param opts - Manifest options including name, schema, dependencies, and hooks
|
||||
* @returns Manifest configuration object
|
||||
*/
|
||||
export function createManifest<Schema extends import('zod').z.AnyZodObject>(
|
||||
export function createManifest<Schema extends AnyObjectSchema>(
|
||||
opts: Pick<Manifest<Schema>, 'name'> & Partial<Omit<Manifest<Schema>, 'name'>>
|
||||
): Manifest<Schema> {
|
||||
return Manifest(opts);
|
||||
|
||||
@@ -6,37 +6,32 @@
|
||||
* @module cubes
|
||||
*/
|
||||
|
||||
// Dependencies
|
||||
export { BuildContext } from './dependencies.js';
|
||||
// Factory functions
|
||||
export {
|
||||
createManifest,
|
||||
manifest,
|
||||
} from './factories.js';
|
||||
// Loader
|
||||
export {
|
||||
findCubeDirectories,
|
||||
getCube,
|
||||
loadCubes,
|
||||
} from './loader.js';
|
||||
export type {
|
||||
AnyObjectSchema,
|
||||
CubeVariables,
|
||||
DependencySpec,
|
||||
Hook,
|
||||
HookContext,
|
||||
LoadResult,
|
||||
} from './types.js';
|
||||
// Types
|
||||
export {
|
||||
Cube,
|
||||
Manifest,
|
||||
} from './types.js';
|
||||
|
||||
export type {
|
||||
Hook,
|
||||
HookContext,
|
||||
LoadResult,
|
||||
CubeVariables,
|
||||
DependencySpec,
|
||||
} from './types.js';
|
||||
|
||||
// Factory functions
|
||||
export {
|
||||
createManifest,
|
||||
manifest,
|
||||
} from './factories.js';
|
||||
|
||||
// Loader
|
||||
export {
|
||||
loadCubes,
|
||||
findCubeDirectories,
|
||||
getCube,
|
||||
} from './loader.js';
|
||||
|
||||
// Dependencies
|
||||
export {
|
||||
BuildContext,
|
||||
} from './dependencies.js';
|
||||
|
||||
// Utilities
|
||||
export { uniqid } from './utils.js';
|
||||
|
||||
@@ -80,7 +80,7 @@ export async function loadCubes(): Promise<LoadResult> {
|
||||
errors.push(`Invalid manifest format in ${manifestPath}: missing 'name'`);
|
||||
} else {
|
||||
const cubeId = extractCubeId(manifest) || path.basename(cubePath);
|
||||
|
||||
|
||||
if (cubes[cubeId]) {
|
||||
errors.push(`Duplicate cube id '${cubeId}'`);
|
||||
return;
|
||||
|
||||
@@ -5,6 +5,13 @@
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* Any object schema, whatever its shape.
|
||||
*
|
||||
* Stands in for zod 3's `z.AnyZodObject`, which zod 4 removed.
|
||||
*/
|
||||
export type AnyObjectSchema = z.ZodObject<Record<string, z.ZodType<any>>>;
|
||||
|
||||
/**
|
||||
* Variables that can be passed to a cube
|
||||
*/
|
||||
@@ -25,7 +32,7 @@ export interface HookContext {
|
||||
/**
|
||||
* Hook function type for before/after cube execution
|
||||
*/
|
||||
export type Hook<Schema extends z.AnyZodObject = z.AnyZodObject> = (
|
||||
export type Hook<Schema extends AnyObjectSchema = AnyObjectSchema> = (
|
||||
ctx: HookContext,
|
||||
variables: z.infer<Schema>
|
||||
) => void | Promise<void>;
|
||||
@@ -33,7 +40,7 @@ export type Hook<Schema extends z.AnyZodObject = z.AnyZodObject> = (
|
||||
/**
|
||||
* User-defined specification for a cube
|
||||
*/
|
||||
export interface Manifest<Schema extends z.AnyZodObject = z.AnyZodObject> {
|
||||
export interface Manifest<Schema extends AnyObjectSchema = AnyObjectSchema> {
|
||||
/** Unique identifier for the cube (used for dependency references) */
|
||||
id: string;
|
||||
/** Human-readable name of the cube */
|
||||
@@ -51,7 +58,7 @@ export interface Manifest<Schema extends z.AnyZodObject = z.AnyZodObject> {
|
||||
/**
|
||||
* Factory function and namespace for Manifest
|
||||
*/
|
||||
export function Manifest<Schema extends z.AnyZodObject>(
|
||||
export function Manifest<Schema extends AnyObjectSchema>(
|
||||
opts: Pick<Manifest<Schema>, 'name'> & Partial<Omit<Manifest<Schema>, 'name'>>
|
||||
): Manifest<Schema> {
|
||||
return {
|
||||
@@ -68,7 +75,7 @@ export namespace Manifest {
|
||||
/**
|
||||
* Internal create helper
|
||||
*/
|
||||
export function create<Schema extends z.AnyZodObject>(
|
||||
export function create<Schema extends AnyObjectSchema>(
|
||||
opts: Pick<Manifest<Schema>, 'name'> & Partial<Omit<Manifest<Schema>, 'name'>>
|
||||
): Manifest<Schema> {
|
||||
return Manifest(opts);
|
||||
@@ -78,7 +85,7 @@ export namespace Manifest {
|
||||
/**
|
||||
* A fully loaded cube with its filesystem location and runtime state
|
||||
*/
|
||||
export class Cube<Schema extends z.AnyZodObject = z.AnyZodObject> {
|
||||
export class Cube<Schema extends AnyObjectSchema = AnyObjectSchema> {
|
||||
constructor(
|
||||
public readonly manifest: Manifest<Schema>,
|
||||
public readonly dir: string,
|
||||
|
||||
+56
-64
@@ -6,81 +6,73 @@
|
||||
|
||||
// Cubes module
|
||||
export * from './cubes/index.js';
|
||||
|
||||
export type {
|
||||
ExecutionConfig,
|
||||
HistoryConfig,
|
||||
LogConfig,
|
||||
LogVerbosity,
|
||||
NopyConfig,
|
||||
NopyConfigFile,
|
||||
ResolutionConfig,
|
||||
ResolutionStrategy,
|
||||
} from './nopy.config.js';
|
||||
// Configuration
|
||||
export { getConfigPaths, loadConfig, logConfigToFlags, saveConfig } from './nopy.config.js';
|
||||
// Backwards compatibility - cubes namespace
|
||||
export { cubes } from './nopy.cubes.js';
|
||||
|
||||
// Main entry point
|
||||
export { nopy } from './nopy.main.js';
|
||||
export type { NopyOptions, NopyResult } from './nopy.main.js';
|
||||
|
||||
export type {
|
||||
DeployCall,
|
||||
ExecutionOptions,
|
||||
ExecutionResult,
|
||||
} from './nopy.executor.js';
|
||||
// Executor
|
||||
export {
|
||||
executeDeployCalls,
|
||||
outputExecutionPlan,
|
||||
summarizeResults,
|
||||
} from './nopy.executor.js';
|
||||
export type {
|
||||
DeployCall,
|
||||
ExecutionResult,
|
||||
ExecutionOptions,
|
||||
} from './nopy.executor.js';
|
||||
|
||||
export type { HistoryEntry, SessionHistory } from './nopy.history.js';
|
||||
// History management
|
||||
export {
|
||||
addToHistory,
|
||||
clearHistory,
|
||||
DEFAULT_HISTORY_SIZE,
|
||||
formatHistoryList,
|
||||
getHistoryPath,
|
||||
getLastSession,
|
||||
getSessionById,
|
||||
HISTORY_FILE,
|
||||
listHistory,
|
||||
loadHistory,
|
||||
removeFromHistory,
|
||||
saveHistory,
|
||||
} from './nopy.history.js';
|
||||
export type { NopyOptions, NopyResult } from './nopy.main.js';
|
||||
// Main entry point
|
||||
export { nopy } from './nopy.main.js';
|
||||
// Prompts
|
||||
export {
|
||||
AuthSelection,
|
||||
CubeSelection,
|
||||
HostSelection,
|
||||
PasswordSelection,
|
||||
VariableAssignment,
|
||||
} from './nopy.prompts.js';
|
||||
export type { AuthSession, CubeSession, NopySession } from './nopy.session.js';
|
||||
// Session management
|
||||
export {
|
||||
createSession,
|
||||
filterInternalVariables,
|
||||
listSessions,
|
||||
loadSession,
|
||||
saveSession,
|
||||
separateEnvAndCubeVariables,
|
||||
} from './nopy.session.js';
|
||||
export type { WorkflowOptions, WorkflowResult } from './nopy.workflow.js';
|
||||
// Workflow
|
||||
export {
|
||||
runWorkflow,
|
||||
runInteractiveWorkflow,
|
||||
runReplayWorkflow,
|
||||
runSessionReplayWorkflow,
|
||||
runWorkflow,
|
||||
} from './nopy.workflow.js';
|
||||
export type { WorkflowOptions, WorkflowResult } from './nopy.workflow.js';
|
||||
|
||||
// Prompts
|
||||
export {
|
||||
CubeSelection,
|
||||
AuthSelection,
|
||||
HostSelection,
|
||||
VariableAssignment,
|
||||
PasswordSelection,
|
||||
} from './nopy.prompts.js';
|
||||
|
||||
// Session management
|
||||
export {
|
||||
loadSession,
|
||||
saveSession,
|
||||
createSession,
|
||||
listSessions,
|
||||
filterInternalVariables,
|
||||
separateEnvAndCubeVariables,
|
||||
} from './nopy.session.js';
|
||||
export type { NopySession, CubeSession, AuthSession } from './nopy.session.js';
|
||||
|
||||
// History management
|
||||
export {
|
||||
loadHistory,
|
||||
saveHistory,
|
||||
addToHistory,
|
||||
getLastSession,
|
||||
getSessionById,
|
||||
listHistory,
|
||||
clearHistory,
|
||||
removeFromHistory,
|
||||
formatHistoryList,
|
||||
getHistoryPath,
|
||||
DEFAULT_HISTORY_SIZE,
|
||||
HISTORY_FILE,
|
||||
} from './nopy.history.js';
|
||||
export type { HistoryEntry, SessionHistory } from './nopy.history.js';
|
||||
|
||||
// Configuration
|
||||
export { loadConfig, saveConfig, logConfigToFlags, getConfigPaths } from './nopy.config.js';
|
||||
export type {
|
||||
NopyConfig,
|
||||
NopyConfigFile,
|
||||
LogConfig,
|
||||
LogVerbosity,
|
||||
HistoryConfig,
|
||||
ExecutionConfig,
|
||||
ResolutionStrategy,
|
||||
ResolutionConfig,
|
||||
} from './nopy.config.js';
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* @module nopy.cli
|
||||
*/
|
||||
|
||||
import { createRequire } from 'node:module';
|
||||
import { Command } from 'commander';
|
||||
import { loadConfig } from './nopy.config.js';
|
||||
import {
|
||||
@@ -16,12 +17,13 @@ import {
|
||||
} from './nopy.history.js';
|
||||
import { nopy } from './nopy.main.js';
|
||||
|
||||
const { version } = createRequire(import.meta.url)('../package.json') as { version: string };
|
||||
|
||||
const program = new Command();
|
||||
const config = loadConfig();
|
||||
|
||||
program
|
||||
.name('nopy')
|
||||
.version('1.0.0')
|
||||
.version(version)
|
||||
.description('A CLI tool for pyinfra script management and execution.')
|
||||
.addHelpText(
|
||||
'after',
|
||||
@@ -61,8 +63,8 @@ program
|
||||
.option('-j, --json', 'Output results as JSON')
|
||||
.option('--no-history', 'Do not save this session to history')
|
||||
.action(async (options) => {
|
||||
// Apply config defaults
|
||||
const execConfig = config.execution ?? {};
|
||||
// Loaded lazily so that --help/--version work outside a configured project.
|
||||
const execConfig = loadConfig().execution ?? {};
|
||||
const continueOnError = options.continueOnError ?? execConfig.continueOnError ?? false;
|
||||
|
||||
try {
|
||||
|
||||
@@ -20,10 +20,10 @@ export const cubes = {
|
||||
|
||||
// Re-export types for direct access
|
||||
export type {
|
||||
Cube,
|
||||
CubeVariables,
|
||||
Hook,
|
||||
HookContext,
|
||||
Cube,
|
||||
Manifest,
|
||||
LoadResult,
|
||||
CubeVariables,
|
||||
Manifest,
|
||||
} from './cubes/index.js';
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
* @module nopy.main
|
||||
*/
|
||||
|
||||
import { type LogRecord, configure, getAnsiColorFormatter, getLogger } from '@logtape/logtape';
|
||||
import { loadCubes } from './cubes/index.js';
|
||||
import { configure, getAnsiColorFormatter, getLogger, type LogRecord } from '@logtape/logtape';
|
||||
import { BuildContext } from './cubes/dependencies.js';
|
||||
import { loadCubes } from './cubes/index.js';
|
||||
import { Variables } from './nopy.common.js';
|
||||
import { getConfigPaths, loadConfig } from './nopy.config.js';
|
||||
import { type ExecutionResult, executeDeployCalls, summarizeResults } from './nopy.executor.js';
|
||||
import { DEFAULT_HISTORY_SIZE, addToHistory } from './nopy.history.js';
|
||||
import { addToHistory, DEFAULT_HISTORY_SIZE } from './nopy.history.js';
|
||||
import { type NopySession, saveSession } from './nopy.session.js';
|
||||
import { runWorkflow } from './nopy.workflow.js';
|
||||
|
||||
@@ -34,12 +34,12 @@ function configureLogtape(): void {
|
||||
loggers: [
|
||||
{
|
||||
category: ['logtape', 'meta'],
|
||||
level: 'error',
|
||||
lowestLevel: 'error',
|
||||
sinks: ['console'],
|
||||
},
|
||||
{
|
||||
category: 'nopy',
|
||||
level: 'debug',
|
||||
lowestLevel: 'debug',
|
||||
sinks: ['console'],
|
||||
},
|
||||
],
|
||||
@@ -52,7 +52,10 @@ configureLogtape();
|
||||
/**
|
||||
* Prints the active configuration summary
|
||||
*/
|
||||
function printActiveConfig(config: import('./nopy.config.js').NopyConfig, opts: { continueOnError: boolean }): void {
|
||||
function printActiveConfig(
|
||||
config: import('./nopy.config.js').NopyConfig,
|
||||
opts: { continueOnError: boolean }
|
||||
): void {
|
||||
const configPaths = getConfigPaths();
|
||||
const cwd = process.cwd();
|
||||
|
||||
@@ -143,12 +146,18 @@ export async function nopy(opts: NopyOptions = {}): Promise<NopyResult | undefin
|
||||
|
||||
if (errors.length > 0) {
|
||||
log.error('Errors found during cube loading:');
|
||||
errors.forEach((error) => log.error(error));
|
||||
for (const error of errors) log.error(error);
|
||||
if (jsonOutput) console.log(JSON.stringify({ success: false, errors }, null, 2));
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const workflow = await runWorkflow(loadSessionPath, cubes, config, { useDefaults, useAuthKey }, replaySession);
|
||||
const workflow = await runWorkflow(
|
||||
loadSessionPath,
|
||||
cubes,
|
||||
config,
|
||||
{ useDefaults, useAuthKey },
|
||||
replaySession
|
||||
);
|
||||
|
||||
// Step 3: Build deployment calls using BuildContext
|
||||
const context = new BuildContext(
|
||||
|
||||
@@ -3,23 +3,31 @@
|
||||
* @module nopy.prompts
|
||||
*/
|
||||
|
||||
// @ts-ignore - no types available
|
||||
import Enquirer from 'enquirer';
|
||||
import fuzzy from 'fuzzy';
|
||||
import inquirer from 'inquirer';
|
||||
// @ts-ignore - no types available
|
||||
import CheckboxPlus from 'inquirer-checkbox-plus-prompt';
|
||||
import { z } from 'zod';
|
||||
import type { Cube } from './cubes/index.js';
|
||||
import type { AnyObjectSchema, Cube } from './cubes/index.js';
|
||||
import type { Variables } from './nopy.common.js';
|
||||
|
||||
// Register the checkbox-plus prompt type for filterable multi-select
|
||||
inquirer.registerPrompt('checkbox-plus', CheckboxPlus);
|
||||
|
||||
interface CubeChoice {
|
||||
/** Submitted value — enquirer returns the `name` of each selected choice. */
|
||||
name: string;
|
||||
value: string;
|
||||
short: string;
|
||||
/** Label rendered in the list. */
|
||||
message: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fuzzy-filters the cube list against what the user has typed so far.
|
||||
*
|
||||
* Handed to enquirer as `suggest`, which calls it on every keystroke with the
|
||||
* current input and the full choice list.
|
||||
*/
|
||||
function suggestCubes(input: string | undefined, choices: CubeChoice[]): CubeChoice[] {
|
||||
if (!input) return choices;
|
||||
return fuzzy
|
||||
.filter(input, choices, { extract: (choice: CubeChoice) => choice.message })
|
||||
.map((result) => result.original);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,9 +39,8 @@ export async function CubeSelection(
|
||||
const cubeChoices: CubeChoice[] = Object.values(cubes)
|
||||
.sort((a, b) => a.id.localeCompare(b.id))
|
||||
.map((cube) => ({
|
||||
name: `${cube.id} - ${cube.name}`,
|
||||
value: cube.id,
|
||||
short: cube.id,
|
||||
name: cube.id,
|
||||
message: `${cube.id} - ${cube.name}`,
|
||||
}));
|
||||
|
||||
// Clear terminal and move cursor to top
|
||||
@@ -45,26 +52,21 @@ export async function CubeSelection(
|
||||
console.log('\n Cube Selection\n');
|
||||
console.log(' Type to filter • Space to select • Enter to confirm\n');
|
||||
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
type: 'checkbox-plus',
|
||||
name: 'selectedCubes',
|
||||
message: 'Select cubes:',
|
||||
pageSize,
|
||||
highlight: true,
|
||||
searchable: true,
|
||||
source: (_answersSoFar: unknown, input: string | undefined) => {
|
||||
const searchTerm = input || '';
|
||||
if (!searchTerm) return Promise.resolve(cubeChoices);
|
||||
const results = fuzzy.filter(searchTerm, cubeChoices, {
|
||||
extract: (choice: CubeChoice) => choice.name,
|
||||
});
|
||||
return Promise.resolve(results.map((r) => r.original));
|
||||
},
|
||||
},
|
||||
]);
|
||||
const prompt = new (Enquirer as any).AutoComplete({
|
||||
name: 'selectedCubes',
|
||||
message: 'Select cubes:',
|
||||
limit: pageSize,
|
||||
multiple: true,
|
||||
choices: cubeChoices,
|
||||
suggest: suggestCubes,
|
||||
});
|
||||
|
||||
return { selectedCubes: answers.selectedCubes };
|
||||
try {
|
||||
return { selectedCubes: await prompt.run() };
|
||||
} catch {
|
||||
// User cancelled
|
||||
return { selectedCubes: [] };
|
||||
}
|
||||
}
|
||||
|
||||
export async function AuthSelection(useAuthKey?: boolean): Promise<{
|
||||
@@ -140,7 +142,7 @@ export async function HostSelection(hosts: string[]): Promise<string> {
|
||||
return selectedHost.customHost ?? selectedHost.host;
|
||||
}
|
||||
|
||||
function coerceValue(value: unknown, zodType: z.ZodTypeAny): unknown {
|
||||
function coerceValue(value: unknown, zodType: z.core.$ZodType): unknown {
|
||||
if (typeof value !== 'string') return value;
|
||||
if (zodType instanceof z.ZodDefault) return coerceValue(value, zodType._def.innerType);
|
||||
if (zodType instanceof z.ZodOptional) return coerceValue(value, zodType._def.innerType);
|
||||
@@ -162,14 +164,14 @@ interface FormChoice {
|
||||
initial: string;
|
||||
}
|
||||
|
||||
export async function VariableAssignment<S extends z.AnyZodObject>(
|
||||
export async function VariableAssignment<S extends AnyObjectSchema>(
|
||||
cube: Cube<S>,
|
||||
variables: Variables
|
||||
) {
|
||||
const schema = cube.manifest.schema.shape;
|
||||
const defaults = cube.getDefaults();
|
||||
const variablesToConfigure: Record<string, unknown> = {};
|
||||
|
||||
|
||||
for (const [key, defaultValue] of Object.entries(defaults)) {
|
||||
if (variables.get(cube.id, 'params')[key] === undefined) {
|
||||
variablesToConfigure[key] = defaultValue;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { getLogger } from '@logtape/logtape';
|
||||
import type { Cube } from './cubes/index.js';
|
||||
import type { NopyConfig } from './nopy.config.js';
|
||||
import { AuthSelection, CubeSelection, HostSelection, PasswordSelection } from './nopy.prompts.js';
|
||||
import { type AuthSession, type NopySession, createSession, loadSession } from './nopy.session.js';
|
||||
import { type AuthSession, createSession, loadSession, type NopySession } from './nopy.session.js';
|
||||
|
||||
const log = getLogger(['nopy', 'workflow']);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user