Skip to content

Commit d3b8531

Browse files
marcelobarretocodex
andcommitted
Add Customer Account EXAF address types
Expose structured extended address fields and address codes on the Customer Account mailing address API so public extension types and reference docs match the runtime data provided by Customer Account Web. Co-authored-by: GPT-5.5 <noreply@openai.com> Orchestrated-by: ae <noreply@shopify.com> Assisted-By: devx/57a4acef-c0db-4da2-b426-7ee2122c2357
1 parent 546b122 commit d3b8531

6 files changed

Lines changed: 331 additions & 16 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/ui-extensions': minor
3+
---
4+
5+
Add structured extended address fields to Customer Account order address APIs.

packages/ui-extensions/docs/surfaces/customer-account/build-docs.mjs

Lines changed: 109 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,100 @@ const cleanupTempFiles = async (tempFiles) => {
6868
);
6969
};
7070

71+
const customerAccountMailingAddressFields = [
72+
{
73+
filePath: 'src/surfaces/customer-account/api/shared.ts',
74+
syntaxKind: 'PropertySignature',
75+
name: 'extendedFields',
76+
value: 'AddressExtendedFields',
77+
description:
78+
'Structured address components for countries and regions that collect them. ' +
79+
"The value is `undefined` when structured address data isn't available " +
80+
'for the order address. Individual fields are `null` when Shopify has ' +
81+
"a structured address record but a specific component wasn't provided.",
82+
isOptional: true,
83+
},
84+
{
85+
filePath: 'src/surfaces/customer-account/api/shared.ts',
86+
syntaxKind: 'PropertySignature',
87+
name: 'addressCode',
88+
value: 'string | null',
89+
description:
90+
'A country-specific address code, such as a short code or postal ' +
91+
"delivery code. The value is `null` when the order address doesn't " +
92+
'have an address code.',
93+
isOptional: true,
94+
examples: [
95+
{
96+
title: 'Example',
97+
description: '',
98+
tabs: [{code: "'01001-000'", title: 'Example'}],
99+
},
100+
],
101+
},
102+
];
103+
104+
const customerAccountMailingAddressValue = ` /**
105+
* Structured address components for countries and regions that collect them.
106+
* The value is \`undefined\` when structured address data isn't available for
107+
* the order address. Individual fields are \`null\` when Shopify has a
108+
* structured address record but a specific component wasn't provided.
109+
*/
110+
extendedFields?: AddressExtendedFields;
111+
112+
/**
113+
* A country-specific address code, such as a short code or postal delivery
114+
* code. The value is \`null\` when the order address doesn't have an address
115+
* code.
116+
*
117+
* @example '01001-000'
118+
*/
119+
addressCode?: string | null;
120+
121+
`;
122+
123+
const addCustomerAccountMailingAddressDocs = async (generatedDocsV2Path) => {
124+
const content = await fs.readFile(generatedDocsV2Path, 'utf8');
125+
const generatedDocs = JSON.parse(content);
126+
const mailingAddressDocs = generatedDocs.MailingAddress;
127+
128+
if (!mailingAddressDocs) return;
129+
130+
const [sourcePath] = Object.keys(mailingAddressDocs);
131+
const docs = mailingAddressDocs[sourcePath];
132+
133+
if (!docs?.members || !docs?.value) return;
134+
135+
const existingMemberNames = new Set(
136+
docs.members.map((member) => member.name),
137+
);
138+
139+
const missingFields = customerAccountMailingAddressFields.filter(
140+
(field) => !existingMemberNames.has(field.name),
141+
);
142+
143+
if (missingFields.length > 0) {
144+
const address2Index = docs.members.findIndex(
145+
(member) => member.name === 'address2',
146+
);
147+
const insertIndex =
148+
address2Index === -1 ? docs.members.length : address2Index + 1;
149+
docs.members.splice(insertIndex, 0, ...missingFields);
150+
}
151+
152+
if (!docs.value.includes('extendedFields?: AddressExtendedFields;')) {
153+
docs.value = docs.value.replace(
154+
' /**\n * The city, town, or village of the address.',
155+
`${customerAccountMailingAddressValue} /**\n * The city, town, or village of the address.`,
156+
);
157+
}
158+
159+
await fs.writeFile(
160+
generatedDocsV2Path,
161+
`${JSON.stringify(generatedDocs, null, 2)}\n`,
162+
);
163+
};
164+
71165
const generateExtensionsDocs = async () => {
72166
console.log(
73167
`Building Customer Account UI Extensions docs for ${EXTENSIONS_API_VERSION} version`,
@@ -98,12 +192,16 @@ const generateExtensionsDocs = async () => {
98192
replaceValue: '',
99193
});
100194

195+
const generatedDocsV2Path = path.join(outputDir, generatedDocsDataV2File);
196+
101197
// Replace 'unstable' with the exact API version in relative doc links
102198
await replaceFileContent({
103-
filePaths: path.join(outputDir, generatedDocsDataV2File),
199+
filePaths: generatedDocsV2Path,
104200
searchValue: '/docs/api//unstable/',
105201
replaceValue: `/docs/api/customer-account-ui-extensions/${EXTENSIONS_API_VERSION}`,
106202
});
203+
204+
await addCustomerAccountMailingAddressDocs(generatedDocsV2Path);
107205
};
108206

109207
let checkoutTempFiles = [];
@@ -126,10 +224,16 @@ try {
126224
// Generate targets.json
127225
console.log('Generating targets.json...');
128226
try {
129-
execSync(`node ${path.join(docsPath, 'build-docs-targets-json.mjs')} ${EXTENSIONS_API_VERSION}`, {
130-
stdio: 'inherit',
131-
cwd: rootPath,
132-
});
227+
execSync(
228+
`node ${path.join(
229+
docsPath,
230+
'build-docs-targets-json.mjs',
231+
)} ${EXTENSIONS_API_VERSION}`,
232+
{
233+
stdio: 'inherit',
234+
cwd: rootPath,
235+
},
236+
);
133237
console.log('✅ Generated targets.json');
134238
} catch (targetsError) {
135239
console.warn(

0 commit comments

Comments
 (0)