Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 70 additions & 2 deletions packages/ui-extensions/docs/surfaces/admin/build-docs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const shopifyDevDBPath = path.join(

const shopifyDevExists = existsSync(shopifyDevPath);

const generatedDocsDataFile = 'generated_docs_data.json';
const generatedDocsDataFile = 'generated_docs_data_v2.json';
const generatedStaticPagesFile = 'generated_static_pages.json';

const componentDefs = path.join(srcPath, 'components.d.ts');
Expand Down Expand Up @@ -250,8 +250,61 @@ const templates = {
}),
};

// Generator outputs v2 format: { [name]: { [filePath]: entry } }. Convert to array for processing.
const v2ToArray = (v2) =>
Object.values(v2).flatMap((byFilePath) => Object.values(byFilePath));

const arrayToV2 = (entries) => {
const v2 = {};
for (const entry of entries) {
const name = entry.name;
const filePath = entry.filePath;
if (!name || !filePath) continue;
if (!v2[name]) v2[name] = {};
v2[name][filePath] = entry;
}
return v2;
};

const transformJson = async (filePath, isExtensions) => {
let jsonData = JSON.parse((await fs.readFile(filePath, 'utf8')).toString());
const outputDir = path.dirname(filePath);

// Generator outputs v2 (object); convert to array for transform steps
if (!Array.isArray(jsonData)) {
jsonData = v2ToArray(jsonData);
}

// Merge reference-entity doc pages (e.g. component descriptions) from collect-doc-pages output
if (isExtensions) {
const docPagesPath = path.join(outputDir, 'doc-pages.json');
if (existsSync(docPagesPath)) {
const docPages = JSON.parse(
(await fs.readFile(docPagesPath, 'utf8')).toString(),
);
const names = new Set(jsonData.map((e) => e.name));
for (const entry of Array.isArray(docPages) ? docPages : []) {
if (!entry.name) continue;
const {
name: _n,
members: _m,
filePath: _f,
syntaxKind: _s,
value: _v,
...docFields
} = entry;
const existingEntries = jsonData.filter((e) => e.name === entry.name);
if (existingEntries.length > 0) {
existingEntries.forEach((existing) =>
Object.assign(existing, docFields),
);
} else {
jsonData.push(entry);
names.add(entry.name);
}
}
}
}

const iconEntry = jsonData.find(
(entry) => entry.name === 'Icon' && entry.subSections,
Expand Down Expand Up @@ -431,7 +484,21 @@ const transformJson = async (filePath, isExtensions) => {
jsonData = [...filteredDocs, ...jsonData];
}

await fs.writeFile(filePath, JSON.stringify(jsonData, null, 2));
if (isExtensions) {
await fs.writeFile(
filePath,
JSON.stringify(arrayToV2(jsonData), null, 2),
);
const arrayPath = path.join(outputDir, 'generated_docs_data.json');
await fs.writeFile(arrayPath, JSON.stringify(jsonData, null, 2));
await replaceFileContent({
filePaths: arrayPath,
searchValue: 'https://shopify.dev',
replaceValue: '',
});
} else {
await fs.writeFile(filePath, JSON.stringify(jsonData, null, 2));
}
};

const generateExtensionsDocs = async () => {
Expand All @@ -450,6 +517,7 @@ const generateExtensionsDocs = async () => {
const scripts = [
`yarn tsc --project ${docsRelativePath}/${tsconfigExtensions} --moduleResolution node --target esNext --module CommonJS`,
`yarn generate-docs --input ./${srcRelativePath} --typesInput ./${srcRelativePath} --output ./${outputDir}`,
`node ${docsRelativePath}/collect-doc-pages.mjs ./${outputDir}`,
`yarn tsc ${docsRelativePath}/staticPages/*.doc.ts --moduleResolution node --target esNext --module CommonJS`,
`yarn generate-docs --isLandingPage --input ./${docsRelativePath}/staticPages --output ./${outputDir}`,
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const shopifyDevDBPath = path.join(
'areas/platforms/shopify-dev/db/data/docs/templated_apis',
);

const generatedDocsDataFile = 'generated_docs_data.json';
const generatedDocsDataFile = 'generated_docs_data_v2.json';
const generatedStaticPagesFile = 'generated_static_pages.json';

const componentDefs = path.join(srcPath, 'components.d.ts');
Expand All @@ -46,7 +46,9 @@ const tsconfig = 'tsconfig.docs.json';
const transformJson = async (filePath) => {
let jsonData = JSON.parse((await fs.readFile(filePath, 'utf8')).toString());

jsonData = jsonData.filter(Boolean);
if (Array.isArray(jsonData)) {
jsonData = jsonData.filter(Boolean);
}
await fs.writeFile(filePath, JSON.stringify(jsonData, null, 2));
};

Expand Down
4 changes: 2 additions & 2 deletions packages/ui-extensions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
],
"devDependencies": {
"@remote-ui/async-subscription": "^2.1.16",
"@shopify/generate-docs": "https://registry.npmjs.org/@shopify/generate-docs/-/generate-docs-0.19.8.tgz",
"@shopify/generate-docs": "^1.0.0",
"@quilted/react-testing": "^0.6.11",
"typescript": "^4.9.0",
"@faker-js/faker": "^8.4.1",
Expand Down Expand Up @@ -172,4 +172,4 @@
"dependencies": {
"ts-morph": "^25.0.1"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {PickerApi} from '../picker/picker';

/**
* The `ActionExtensionApi` object provides methods for action extensions that render in modal overlays. Access the following properties on the `ActionExtensionApi` object to interact with the current context, control the modal, and display picker dialogs.
* @publicDocs
*/
export interface ActionExtensionApi<ExtensionTarget extends AnyExtensionTarget>
extends StandardApi<ExtensionTarget> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface Navigation {

/**
* The `BlockExtensionApi` object provides methods for block extensions that render inline content on admin pages. Access the following properties on the `BlockExtensionApi` object to interact with the current context, navigate to other extensions, and display picker dialogs.
* @publicDocs
*/
export interface BlockExtensionApi<ExtensionTarget extends AnyExtensionTarget>
extends StandardApi<ExtensionTarget> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {ExtensionTarget as AnyExtensionTarget} from '../../extension-target

/**
* The `CustomerSegmentTemplateApi` object provides methods for creating customer segment templates. Access the following properties on the `CustomerSegmentTemplateApi` object to build templates with translated content.
* @publicDocs
*/
export interface CustomerSegmentTemplateApi<
ExtensionTarget extends AnyExtensionTarget,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* The response returned when a merchant closes or cancels the workflow without completing it. Check for this response to handle cancellation gracefully in your extension.
* @publicDocs
*/
export interface ClosedIntentResponse {
/** Indicates the workflow was closed without completion. When `'closed'`, the merchant exited the workflow before finishing. */
Expand All @@ -8,6 +9,7 @@ export interface ClosedIntentResponse {

/**
* The response returned when a merchant successfully completes the workflow. Use this to access the created or updated resource data.
* @publicDocs
*/
export interface SuccessIntentResponse {
/** Indicates successful completion. When `'ok'`, the merchant completed the workflow and the resource was created or updated. */
Expand All @@ -18,6 +20,7 @@ export interface SuccessIntentResponse {

/**
* The response returned when the workflow fails due to validation errors or other issues. Use this to display error messages and help merchants fix problems.
* @publicDocs
*/
export interface ErrorIntentResponse {
/** Indicates the workflow failed. When `'error'`, the workflow encountered validation errors or other issues that prevented completion. */
Expand All @@ -37,6 +40,7 @@ export interface ErrorIntentResponse {

/**
* The result of an intent workflow. Check the `code` property to determine the outcome: `'ok'` for success, `'error'` for failure, or `'closed'` if the merchant cancelled.
* @publicDocs
*/
export type IntentResponse =
| SuccessIntentResponse
Expand All @@ -45,6 +49,7 @@ export type IntentResponse =

/**
* A handle for tracking an in-progress intent workflow.
* @publicDocs
*/
export interface IntentActivity {
/**
Expand Down Expand Up @@ -127,6 +132,7 @@ export interface IntentQuery extends IntentQueryOptions {
* });
* const response = await activity.complete;
* ```
* @publicDocs
*/
export interface IntentInvokeApi {
(query: IntentQuery): Promise<IntentActivity>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {Data} from './data';

/**
* The `OrderRoutingRuleApi` object provides methods for configuring order routing rules. Access the following properties on the `OrderRoutingRuleApi` object to manage rule settings and metafields.
* @publicDocs
*/
export interface OrderRoutingRuleApi<ExtensionTarget extends AnyExtensionTarget>
extends StandardApi<ExtensionTarget> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,6 @@ interface Item {

/**
* The `picker` function opens a custom selection dialog with your app-specific data. It accepts configuration options to define the picker's heading, items, headers, and selection behavior. It returns a Promise that resolves to a `Picker` object with a `selected` property for accessing the merchant's selection.
* @publicDocs
*/
export type PickerApi = (options: PickerOptions) => Promise<Picker>;
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {PickerApi} from '../picker/picker';

/**
* The `PrintActionExtensionApi` object provides methods for print action extensions that generate custom printable documents. Access the following properties on the `PrintActionExtensionApi` object to access selected resources and display picker dialogs for print configuration.
* @publicDocs
*/
export interface PrintActionExtensionApi<
ExtensionTarget extends AnyExtensionTarget,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export interface ProductComponent {

/**
* The `ProductDetailsConfigurationApi` object provides methods for configuring product bundles and relationships. Access the following properties on the `ProductDetailsConfigurationApi` object to build product configuration interfaces.
* @publicDocs
*/
export interface ProductDetailsConfigurationApi<
ExtensionTarget extends AnyExtensionTarget,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export interface ProductVariantComponent {

/**
* The `ProductVariantDetailsConfigurationApi` object provides methods for configuring product variant bundles and relationships. Access the following properties on the `ProductVariantDetailsConfigurationApi` object to build variant configuration interfaces.
* @publicDocs
*/
export interface ProductVariantDetailsConfigurationApi<
ExtensionTarget extends AnyExtensionTarget,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {ExtensionTarget as AnyExtensionTarget} from '../extension-targets';

/**
* The `PurchaseOptionsCardConfigurationApi` object provides methods for action extensions that interact with purchase options and selling plans. Access the following properties on the `PurchaseOptionsCardConfigurationApi` object to work with selected products and their associated subscription configurations.
* @publicDocs
*/
export interface PurchaseOptionsCardConfigurationApi<
ExtensionTarget extends AnyExtensionTarget,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ interface Filters {

/**
* The `ResourcePickerOptions` object defines how the resource picker behaves, including which resource type to display, selection limits, filters, and preselected items. Access the following properties on the `ResourcePickerOptions` object to configure the resource picker's appearance and functionality.
* @publicDocs
*/
export interface ResourcePickerOptions {
/**
Expand Down Expand Up @@ -394,6 +395,7 @@ export interface ResourcePickerOptions {

/**
* Opens the resource picker modal for selecting products, variants, or collections. Returns the selected resources when the user confirms their selection, or undefined if they cancel.
* @publicDocs
*/
export type ResourcePickerApi = (
options: ResourcePickerOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface ShouldRenderOutput {

/**
* The `ShouldRenderApi` object provides methods for controlling action extension visibility. Access the following properties on the `ShouldRenderApi` object to determine whether an associated action should appear based on the current context.
* @publicDocs
*/
export interface ShouldRenderApi<ExtensionTarget extends AnyExtensionTarget>
extends StandardApi<ExtensionTarget> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ interface Auth {

/**
* The `StandardApi` object provides core methods available to all extension targets. Access the following properties on the `StandardApi` object to authenticate users, query the [GraphQL Admin API](/docs/api/admin-graphql), translate content, handle intents, and persist data.
* @publicDocs
*/
export interface StandardApi<ExtensionTarget extends AnyExtensionTarget> {
/**
Expand Down
Loading
Loading