Extract path from AppConfiguration into App.configPath#6949
Draft
ryancbahan wants to merge 2 commits intomainfrom
Draft
Extract path from AppConfiguration into App.configPath#6949ryancbahan wants to merge 2 commits intomainfrom
ryancbahan wants to merge 2 commits intomainfrom
Conversation
This was referenced Mar 6, 2026
Contributor
Author
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
This was referenced Mar 6, 2026
Contributor
Coverage report
Test suite run success3830 tests passing in 1466 suites. Report generated by 🧪jest coverage report action from 29d8b4d |
ae09959 to
6a0f47a
Compare
This was referenced Mar 7, 2026
405c900 to
74e0e58
Compare
3813e7f to
530df59
Compare
74e0e58 to
6e51da6
Compare
530df59 to
fcff02d
Compare
c1e50a8 to
8ae41eb
Compare
fcff02d to
5028d72
Compare
Contributor
Differences in type declarationsWe detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:
New type declarationspackages/cli-kit/dist/public/node/toml/codec.d.tsimport { JsonMap } from '../../../private/common/json.js';
export type JsonMapType = JsonMap;
/**
* Given a TOML string, it returns a JSON object.
*
* @param input - TOML string.
* @returns JSON object.
*/
export declare function decodeToml(input: string): JsonMapType;
/**
* Given a JSON object, it returns a TOML string.
*
* @param content - JSON object.
* @returns TOML string.
*/
export declare function encodeToml(content: JsonMap | object): string;
packages/cli-kit/dist/public/node/toml/index.d.tsexport type { JsonMapType } from './codec.js';
packages/cli-kit/dist/public/node/toml/toml-file.d.tsimport { JsonMapType } from './codec.js';
/**
* Thrown when a TOML file cannot be parsed. Includes the file path for context.
*/
export declare class TomlParseError extends Error {
readonly path: string;
constructor(path: string, cause: Error);
}
/**
* General-purpose TOML file abstraction.
*
* Provides a unified interface for reading, patching, removing keys from, and replacing
* the content of TOML files on disk.
*
* - `read` populates content from disk
* - `patch` does surgical WASM-based edits (preserves comments and formatting)
* - `remove` deletes a key by dotted path (preserves comments and formatting)
* - `replace` does a full re-serialization (comments and formatting are NOT preserved).
* - `transformRaw` applies a function to the raw TOML string on disk.
*/
export declare class TomlFile {
/**
* Read and parse a TOML file from disk. Throws if the file doesn't exist or contains invalid TOML.
* Parse errors are wrapped in {@link TomlParseError} with the file path for context.
*
* @param path - Absolute path to the TOML file.
* @returns A TomlFile instance with parsed content.
*/
static read(path: string): Promise<TomlFile>;
readonly path: string;
content: JsonMapType;
constructor(path: string, content: JsonMapType);
/**
* Surgically patch values in the TOML file, preserving comments and formatting.
*
* Accepts a nested object whose leaf values are set in the TOML. Intermediate tables are
* created automatically. Setting a leaf to `undefined` removes it (use `remove()` for a
* clearer API when deleting keys).
*
* @example
* ```ts
* await file.patch({build: {dev_store_url: 'my-store.myshopify.com'}})
* await file.patch({application_url: 'https://example.com', auth: {redirect_urls: ['...']}})
* ```
*/
patch(changes: {
[key: string]: unknown;
}): Promise<void>;
/**
* Remove a key from the TOML file by dotted path, preserving comments and formatting.
*
* @param keyPath - Dotted key path to remove (e.g. 'build.include_config_on_deploy').
* @example
* ```ts
* await file.remove('build.include_config_on_deploy')
* ```
*/
remove(keyPath: string): Promise<void>;
/**
* Replace the entire file content. The file is fully re-serialized — comments and formatting
* are NOT preserved.
*
* @param content - The new content to write.
* @example
* ```ts
* await file.replace({client_id: 'abc', name: 'My App'})
* ```
*/
replace(content: JsonMapType): Promise<void>;
/**
* Transform the raw TOML string on disk. Reads the file, applies the transform function
* to the raw text, writes back, and re-parses to keep `content` in sync.
*
* Use this for text-level operations that can't be expressed as structured edits —
* e.g. Injecting comments or positional insertion of keys in arrays-of-tables.
* Subsequent `patch()` calls will preserve any comments added this way.
*
* @param transform - A function that receives the raw TOML string and returns the modified string.
* @example
* ```ts
* await file.transformRaw((raw) => `# Header comment\n${raw}`)
* ```
*/
transformRaw(transform: (raw: string) => string): Promise<void>;
private decode;
}
Existing type declarationsWe found no diffs with existing type declarations |
8ae41eb to
a29ba87
Compare
5028d72 to
49d9789
Compare
5 tasks
a29ba87 to
dab1a61
Compare
Path is not data — it's metadata about where the config file lives,
not part of what the TOML file contains. This is the first step toward
making AppConfiguration a trustworthy, file-shaped type.
- Add `configPath: string` to App, AppInterface, AppConfigurationInterface
- Remove `& {path: string}` from AppConfiguration, BasicAppConfigurationWithoutModules, LegacyAppConfiguration
- Delete AppConfigurationWithoutPath (replaced by AppConfiguration)
- Simplify SchemaForConfig (no more Omit<..., 'path'>)
- parseConfigurationFile no longer bolts path onto return value
- writeAppConfigurationFile takes explicit configPath parameter
- Type guards pass objects directly (no destructuring to strip path)
- Migrate ~24 callsites from app.configuration.path → app.configPath
- Remove 10 workarounds (delete file.path, blocklist, Omit wrappers)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
49d9789 to
29d8b4d
Compare
dab1a61 to
2378a7f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

WHY are these changes introduced?
AppConfigurationcarries apathfield that was never part of any TOML schema. It was bolted on byparseConfigurationFileand then worked around everywhere:Omit<..., 'path'>on schema types,delete file.pathbefore re-validation, destructuring to strip it in type guards, a blocklist to prevent writing it back to disk.This PR adds a clearer app config model:
AppConfigurationdescribes what's in the TOML file. Nothing more.WHAT is this pull request doing?
Moves
pathfrom the configuration type to the app model:App.configPath: string— path is metadata about the app, not part of its config (same patternExtensionInstanceuses withconfigurationPath)AppConfiguration— removes& {path: string}intersection from all 3 config typesAppConfigurationWithoutPath— deleted (was a band-aid), 8 usages replaced withAppConfigurationSchemaForConfig— simplified toZodObjectOf<TConfig>(no moreOmit)parseConfigurationFile— no longer appends{path: filepath}to return valuewriteAppConfigurationFile— takes explicitconfigPathparameterpathapp.configuration.path→app.configPathBehaviorally, this is a no-op.
How to test your changes?
Config pipeline snapshot tests confirm no change in TOML output.
Measuring impact
Checklist