Abstract build steps to externalize the build configuration#6866
Abstract build steps to externalize the build configuration#6866alfonso-noriega wants to merge 1 commit intomainfrom
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Coverage report
Test suite run success3817 tests passing in 1460 suites. Report generated by 🧪jest coverage report action from ce4a75e |
c4c3353 to
d2a2b21
Compare
510502e to
f9f6e10
Compare
27b8cfc to
34005f5
Compare
|
We detected some changes at Caution DO NOT create changesets for features which you do not wish to be included in the public changelog of the next CLI release. |
34005f5 to
c2808f7
Compare
f9f6e10 to
ff3f4e0
Compare
445a4c4 to
f14e0e0
Compare
ff3f4e0 to
635fedb
Compare
635fedb to
66deccf
Compare
f14e0e0 to
ef0c29e
Compare
| const destPath = joinPath(outputDir, destination) | ||
| await mkdir(dirname(destPath)) | ||
| await copyFile(sourcePath, destPath) | ||
| options.stdout.write(`Copied ${source} to ${destination}\n`) |
There was a problem hiding this comment.
copy_files destination path can escape outputDir (arbitrary write)
copySourceEntry builds destPath via joinPath(outputDir, destination). If destination is absolute or contains .., the resolved path can escape outputDir, enabling a build config (notably described as serializable/externalizable) to overwrite arbitrary files on the machine.
Evidence:
const destPath = joinPath(outputDir, destination)
await mkdir(dirname(destPath))
await copyFile(sourcePath, destPath)Impact includes overwriting repo/CI files, compromising developer/CI machines, supply-chain risk, and corrupted artifacts.
| resolvedPatterns, | ||
| resolvedIgnore, | ||
| definition.preserveStructure, | ||
| options, |
There was a problem hiding this comment.
copy_files pattern destination directory can escape outputDir (arbitrary write)
In pattern mode, definition.destination is joined into outputDir without sanitization:
const destinationDir = definition.destination ? joinPath(outputDir, definition.destination) : outputDirAbsolute paths or .. segments can escape outputDir, after which copyByPattern will create directories and write files there—especially dangerous because it can write many files outside the build output.
| const outputFile = joinPath(extension.outputPath, relativePathName) | ||
| if (filepath === outputFile) return | ||
| await copyFile(filepath, outputFile) | ||
| }), |
There was a problem hiding this comment.
Theme bundling writes under extension.outputPath and doesn’t ensure parent dirs exist
executeBundleThemeStep computes:
const outputFile = joinPath(extension.outputPath, relativePathName)
await copyFile(filepath, outputFile)If extension.outputPath is a file path (e.g., .../extension.js), this produces .../extension.js/<relative> and fails. Also, it does not mkdir(dirname(outputFile)), so nested paths fail unless directories already exist.
| } | ||
| return copySourceEntry(entry.source, entry.destination, baseDir, outputDir, options, preserveStructure) | ||
| }), | ||
| ) |
There was a problem hiding this comment.
Unbounded Promise.all copies can exhaust file descriptors on large file sets
Multiple places use Promise.all over potentially large arrays (copyFilesList, copyTomlKeyEntry, copyByPattern). For thousands of files, this can trigger EMFILE: too many open files, high memory usage, and flaky builds.
|
🤖 Code Review · #projects-dev-ai for questions ✅ Complete - No issues 📋 History✅ 4 findings → ✅ 1 findings → ✅ No issues → ✅ 2 findings → ✅ No issues |
66deccf to
ae7ed38
Compare
ef0c29e to
644b571
Compare
644b571 to
d9664fc
Compare
|
|
||
| await mkdir(dirname(destPath)) | ||
| await copyFile(filepath, destPath) | ||
| }), |
There was a problem hiding this comment.
copyByPattern can overwrite files when preserveStructure: false due to basename collisions
When preserveStructure is false, destination paths are set to basename(filepath):
const relPath = preserveStructure ? relativePath(sourceDir, filepath) : basename(filepath)If multiple matched files share the same basename from different subdirectories (e.g., index.js, schema.json), later copies silently overwrite earlier ones.
|
These findings are in files not modified by this PR and cannot be posted as inline comments.
Evidence: const mode = this.specification.buildConfig.mode |
9964055 to
d835caf
Compare
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 declarationsWe found no new type declarations in this PR Existing type declarationspackages/cli-kit/dist/private/node/conf-store.d.ts@@ -21,8 +21,6 @@ interface Cache {
export interface ConfSchema {
sessionStore: string;
currentSessionId?: string;
- devSessionStore?: string;
- currentDevSessionId?: string;
cache?: Cache;
}
/**
packages/cli-kit/dist/private/node/session/exchange.d.ts@@ -6,6 +6,20 @@ export declare class InvalidGrantError extends ExtendableError {
}
export declare class InvalidRequestError extends ExtendableError {
}
+export interface ExchangeScopes {
+ admin: string[];
+ partners: string[];
+ storefront: string[];
+ businessPlatform: string[];
+ appManagement: string[];
+}
+/**
+ * Given an identity token, request an application token.
+ * @param identityToken - access token obtained in a previous step
+ * @param store - the store to use, only needed for admin API
+ * @returns An array with the application access tokens.
+ */
+export declare function exchangeAccessForApplicationTokens(identityToken: IdentityToken, scopes: ExchangeScopes, store?: string): Promise<Record<string, ApplicationToken>>;
/**
* Given an expired access token, refresh it to get a new one.
*/
packages/cli-kit/dist/private/node/session/schema.d.ts@@ -12,8 +12,8 @@ declare const IdentityTokenSchema: zod.ZodObject<{
}, "strip", zod.ZodTypeAny, {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
}, {
@@ -34,8 +34,8 @@ declare const ApplicationTokenSchema: zod.ZodObject<{
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -54,8 +54,8 @@ declare const SessionSchema: zod.ZodObject<{
}, "strip", zod.ZodTypeAny, {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
}, {
@@ -73,8 +73,8 @@ declare const SessionSchema: zod.ZodObject<{
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -88,8 +88,8 @@ declare const SessionSchema: zod.ZodObject<{
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -103,8 +103,8 @@ declare const SessionSchema: zod.ZodObject<{
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -116,16 +116,16 @@ declare const SessionSchema: zod.ZodObject<{
identity: {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
};
applications: {} & {
[k: string]: {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
};
};
@@ -166,8 +166,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
}, "strip", zod.ZodTypeAny, {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
}, {
@@ -185,8 +185,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -200,8 +200,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -215,8 +215,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -228,16 +228,16 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
identity: {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
};
applications: {} & {
[k: string]: {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
};
};
@@ -269,8 +269,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
}, "strip", zod.ZodTypeAny, {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
}, {
@@ -288,8 +288,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -303,8 +303,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -318,8 +318,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -331,16 +331,16 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
identity: {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
};
applications: {} & {
[k: string]: {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
};
};
@@ -372,8 +372,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
}, "strip", zod.ZodTypeAny, {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
}, {
@@ -391,8 +391,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -406,8 +406,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -421,8 +421,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -434,16 +434,16 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
identity: {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
};
applications: {} & {
[k: string]: {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
};
};
@@ -475,8 +475,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
}, "strip", zod.ZodTypeAny, {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
}, {
@@ -494,8 +494,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -509,8 +509,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -524,8 +524,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -537,16 +537,16 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
identity: {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
};
applications: {} & {
[k: string]: {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
};
};
@@ -578,8 +578,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
}, "strip", zod.ZodTypeAny, {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
}, {
@@ -597,8 +597,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -612,8 +612,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -627,8 +627,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -640,16 +640,16 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
identity: {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
};
applications: {} & {
[k: string]: {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
};
};
@@ -681,8 +681,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
}, "strip", zod.ZodTypeAny, {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
}, {
@@ -700,8 +700,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -715,8 +715,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -730,8 +730,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -743,16 +743,16 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
identity: {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
};
applications: {} & {
[k: string]: {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
};
};
@@ -784,8 +784,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
}, "strip", zod.ZodTypeAny, {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
}, {
@@ -803,8 +803,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -818,8 +818,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -833,8 +833,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -846,16 +846,16 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
identity: {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
};
applications: {} & {
[k: string]: {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
};
};
@@ -887,8 +887,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
}, "strip", zod.ZodTypeAny, {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
}, {
@@ -906,8 +906,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -921,8 +921,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -936,8 +936,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -949,16 +949,16 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
identity: {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
};
applications: {} & {
[k: string]: {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
};
};
@@ -990,8 +990,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
}, "strip", zod.ZodTypeAny, {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
}, {
@@ -1009,8 +1009,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -1024,8 +1024,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -1039,8 +1039,8 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
storeFqdn: zod.ZodOptional<zod.ZodString>;
}, "strip", zod.ZodTypeAny, {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
}, {
accessToken: string;
@@ -1052,16 +1052,16 @@ export declare const SessionsSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{}
identity: {
accessToken: string;
refreshToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
userId: string;
alias?: string | undefined;
};
applications: {} & {
[k: string]: {
accessToken: string;
- expiresAt: Date;
scopes: string[];
+ expiresAt: Date;
storeFqdn?: string | undefined;
};
};
packages/cli-kit/dist/private/node/session/validate.d.ts@@ -1,11 +1,12 @@
import { Session } from './schema.js';
+import { OAuthApplications } from '../session.js';
type ValidationResult = 'needs_refresh' | 'needs_full_auth' | 'ok';
/**
- * Validate if the current session is valid or we need to refresh/re-authenticate.
- * With PCAT, only the identity token needs validation - no per-application tokens.
+ * Validate if the current session is valid or we need to refresh/re-authenticate
* @param scopes - requested scopes to validate
- * @param session - current session with identity token
+ * @param applications - requested applications
+ * @param session - current session with identity and application tokens
* @returns 'ok' if the session is valid, 'needs_full_auth' if we need to re-authenticate, 'needs_refresh' if we need to refresh the session
*/
-export declare function validateSession(scopes: string[], session: Session | undefined): Promise<ValidationResult>;
+export declare function validateSession(scopes: string[], applications: OAuthApplications, session: Session | undefined): Promise<ValidationResult>;
export {};
\ No newline at end of file
packages/cli-kit/dist/private/node/testing/ui.d.ts@@ -73,8 +73,7 @@ export declare function sendInputAndWait(renderInstance: ReturnType<typeof rende
export declare function sendInputAndWaitForContent(renderInstance: ReturnType<typeof render>, content: string, ...inputs: string[]): Promise<void>;
/** Function that is useful when you want to check the last frame of a component that unmounted.
*
- * With Ink 6 / React 19, the output is no longer cleared on unmount,
- * so lastFrame() consistently returns the last rendered content.
+ * The reason this function exists is that in CI Ink will clear the last frame on unmount.
*/
export declare function getLastFrameAfterUnmount(renderInstance: ReturnType<typeof render>): string | undefined;
type TrackedPromise<T> = Promise<T> & {
packages/cli-kit/dist/private/node/ui/components/SelectInput.d.ts@@ -1,5 +1,8 @@
import React from 'react';
import { DOMElement } from 'ink';
+declare module 'react' {
+ function forwardRef<T, TProps>(render: (props: TProps, ref: React.Ref<T>) => React.ReactElement | null): (props: TProps & React.RefAttributes<T>) => React.ReactElement | null;
+}
export interface SelectInputProps<T> {
items: Item<T>[];
initialItems?: Item<T>[];
@@ -15,8 +18,7 @@ export interface SelectInputProps<T> {
morePagesMessage?: string;
availableLines?: number;
onSubmit?: (item: Item<T>) => void;
- inputFixedAreaRef?: React.Ref<DOMElement>;
- ref?: React.Ref<DOMElement>;
+ inputFixedAreaRef?: React.RefObject<DOMElement>;
groupOrder?: string[];
}
export interface Item<T> {
@@ -27,5 +29,4 @@ export interface Item<T> {
helperText?: string;
disabled?: boolean;
}
-declare function SelectInput<T>({ items: rawItems, initialItems, onChange, enableShortcuts, focus, emptyMessage, defaultValue, highlightedTerm, loading, errorMessage, hasMorePages, morePagesMessage, availableLines, onSubmit, inputFixedAreaRef, ref, groupOrder, }: SelectInputProps<T>): React.ReactElement | null;
-export { SelectInput };
\ No newline at end of file
+export declare const SelectInput: <T>(props: SelectInputProps<T> & React.RefAttributes<DOMElement>) => React.ReactElement | null;
\ No newline at end of file
|
d835caf to
ef058d2
Compare
ae7ed38 to
b255e6d
Compare
57a0790 to
316c2ab
Compare
b255e6d to
0202391
Compare
316c2ab to
a9d3692
Compare
| await copyFile(sourcePath, destPath) | ||
| options.stdout.write(`Copied ${source} to ${destination}\n`) | ||
| return 1 | ||
| } |
There was a problem hiding this comment.
copySourceEntry copies directories incorrectly when destination is set
In copySourceEntry, when destination is provided, the code always uses copyFile(sourcePath, destPath), but source can be a directory (per the step semantics and schema). Copying a directory as a file will throw and fail the build for valid configs that specify a directory + destination.
| duration: Date.now() - startTime, | ||
| error: stepError, | ||
| } | ||
| } |
There was a problem hiding this comment.
executeStep never writes results into context.stepResults (pipeline contract not met)
executeStep returns a StepResult and never stores it into context.stepResults, despite the stated intention that later steps can read outputs from earlier ones. This breaks the centralized pipeline behavior and will cause later steps to silently fail/misbehave if they rely on stepResults.
a9d3692 to
ce4a75e
Compare

Abstract build steps to externalize the build configuration
Summary
This PR introduces a client steps build pipeline — a declarative, composable replacement for the existing mode-based
BuildConfigdispatch. Extension specifications now declare an explicit list of typed build steps, each with its own configuration and executor, instead of relying on a hard-coded switch overbuildConfig.mode.The main additions are:
ClientStep/ClientStepstypes and theexecuteSteprunnerexecuteStepByType) that dispatches to type-specific executorsbundle_ui,build_theme,bundle_theme,build_function,create_tax_stub,copy_static_assets,include_assetsinclude_assetsstep with a flexibleinclusionscontract (pattern, static, configKey)clientStepsfield added toExtensionSpecificationwith full factory supportBuildConfigsimplified from a discriminated union to a flat interface (transitional — to be removed once all consumers migrate)Architecture
Core types
executeStepwraps execution with timing and error handling. Results are stored incontext.stepResultskeyed bystep.id, making them available to downstream steps.Step types
bundle_uiDelegates to the existing
buildUIExtension().build_themeRuns theme-check validation via
runThemeCheck().bundle_themeCopies theme files to output preserving relative paths, using
themeExtensionFiles()(respects.shopifyignore).build_functionDelegates to
buildFunctionExtension()(wasm-opt, trampoline).create_tax_stubWrites a minimal
(()=>{})();stub toextension.outputPath.copy_static_assetsCalls
extension.copyStaticAssets().include_assetsCopies files from various sources into the output directory. All inclusions run in parallel. Returns
{filesCopied: number}.Config schema
type: 'pattern'— glob-basedExample — copy only spec files from a subdirectory, preserving structure:
type: 'static'— explicit source pathdestinationpreserveStructurefalse(default)truetype: 'configKey'— config-driven sourceResolves a path (or array of paths) from the extension's TOML config. Supports TOML array-of-tables traversal. Silently skipped if the key is absent or the path does not exist.
Changes to
specification.tsNew field on
ExtensionSpecificationclientSteps: ClientStepsAll three factory functions now accept and default
clientSteps:BuildConfigsimplifiedOld (discriminated union —
filePatternsonly valid oncopy_files):New (flat interface — transitional, to be removed once
clientStepsfully replaces it):Wiring a spec
Copy-files pattern (e.g. channel, flow_template):
Not yet implemented
Declared in
ClientStep.typefor future use, throw"not yet implemented"if called:esbuildvalidatetransformcustomFiles changed
services/build/client-steps.tsClientStep,ClientSteps,BuildContext,StepResult,executeStepservices/build/steps/index.tsexecuteStepByTyperouterservices/build/steps/include_assets_step.tsservices/build/steps/bundle-ui-step.tsbuildUIExtensionservices/build/steps/build-theme-step.tsrunThemeCheckservices/build/steps/bundle-theme-step.tsthemeExtensionFilesservices/build/steps/build-function-step.tsbuildFunctionExtensionservices/build/steps/create-tax-stub-step.tsservices/build/steps/copy-static-assets-step.tsextension.copyStaticAssets()models/extensions/specification.tsclientSteps: ClientSteps; simplifiedBuildConfig; updated all three factory functionsmodels/extensions/extension-instance.tsfilePatterns ?? []fallbacks for optionalBuildConfigfieldsclient-steps.test.ts,client-steps.integration.test.ts,include-assets-step.test.tsMeasuring impact
How do we know this change was effective? Please choose one:
Checklist