diff --git a/AGENTS.md b/AGENTS.md index 333ab540..5426eaa0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -23,3 +23,26 @@ - when logging use the logger instance from `@salesforce/b2c-tooling/logger` package - CLI commands have access to this logger via `this.log` method from oclif Command class - CLI commands can write directly to stdout/stderr if their primary purpose is to output or stream data + +## Table Output + +When rendering tabular data in CLI commands, use the shared `TableRenderer` utility from `@salesforce/b2c-tooling/cli`: + +```typescript +import { createTable, type ColumnDef } from '@salesforce/b2c-tooling/cli'; + +// Define columns with header and getter function +const COLUMNS: Record> = { + id: { header: 'ID', get: (item) => item.id }, + name: { header: 'Name', get: (item) => item.name }, + status: { header: 'Status', get: (item) => item.status }, +}; + +// Render the table +createTable(COLUMNS).render(data, ['id', 'name', 'status']); +``` + +Features: +- Dynamic column widths based on content +- Supports `extended` flag on columns for optional fields +- Use `TableRenderer` class directly for column validation helpers (e.g., `--columns` flag support) diff --git a/packages/b2c-cli/src/commands/code/list.ts b/packages/b2c-cli/src/commands/code/list.ts index 82d5ad1e..953d2338 100644 --- a/packages/b2c-cli/src/commands/code/list.ts +++ b/packages/b2c-cli/src/commands/code/list.ts @@ -1,9 +1,33 @@ import {ux} from '@oclif/core'; -import cliui from 'cliui'; -import {InstanceCommand} from '@salesforce/b2c-tooling/cli'; +import {InstanceCommand, createTable, type ColumnDef} from '@salesforce/b2c-tooling/cli'; import {listCodeVersions, type CodeVersion, type CodeVersionResult} from '@salesforce/b2c-tooling/operations/code'; import {t} from '../../i18n/index.js'; +const COLUMNS: Record> = { + id: { + header: 'ID', + get: (v) => v.id || '-', + }, + active: { + header: 'Active', + get: (v) => (v.active ? 'Yes' : 'No'), + }, + rollback: { + header: 'Rollback', + get: (v) => (v.rollback ? 'Yes' : 'No'), + }, + lastModified: { + header: 'Last Modified', + get: (v) => (v.last_modification_time ? new Date(v.last_modification_time).toLocaleString() : '-'), + }, + cartridges: { + header: 'Cartridges', + get: (v) => String(v.cartridges?.length ?? 0), + }, +}; + +const DEFAULT_COLUMNS = ['id', 'active', 'rollback', 'lastModified', 'cartridges']; + export default class CodeList extends InstanceCommand { static description = t('commands.code.list.description', 'List code versions on a B2C Commerce instance'); @@ -41,42 +65,8 @@ export default class CodeList extends InstanceCommand { return result; } - this.printVersionsTable(versions); + createTable(COLUMNS).render(versions, DEFAULT_COLUMNS); return result; } - - private printVersionsTable(versions: CodeVersion[]): void { - const ui = cliui({width: process.stdout.columns || 80}); - - // Header - ui.div( - {text: 'ID', width: 25, padding: [0, 2, 0, 0]}, - {text: 'Active', width: 10, padding: [0, 2, 0, 0]}, - {text: 'Rollback', width: 10, padding: [0, 2, 0, 0]}, - {text: 'Last Modified', width: 25, padding: [0, 2, 0, 0]}, - {text: 'Cartridges', padding: [0, 0, 0, 0]}, - ); - - // Separator - ui.div({text: '─'.repeat(80), padding: [0, 0, 0, 0]}); - - // Rows - for (const version of versions) { - const lastModified = version.last_modification_time - ? new Date(version.last_modification_time).toLocaleString() - : '-'; - const cartridgeCount = version.cartridges?.length ?? 0; - - ui.div( - {text: version.id || '', width: 25, padding: [0, 2, 0, 0]}, - {text: version.active ? 'Yes' : 'No', width: 10, padding: [0, 2, 0, 0]}, - {text: version.rollback ? 'Yes' : 'No', width: 10, padding: [0, 2, 0, 0]}, - {text: lastModified, width: 25, padding: [0, 2, 0, 0]}, - {text: String(cartridgeCount), padding: [0, 0, 0, 0]}, - ); - } - - ux.stdout(ui.toString()); - } } diff --git a/packages/b2c-cli/src/commands/job/search.ts b/packages/b2c-cli/src/commands/job/search.ts index ef4a8196..95af973e 100644 --- a/packages/b2c-cli/src/commands/job/search.ts +++ b/packages/b2c-cli/src/commands/job/search.ts @@ -1,6 +1,5 @@ import {Flags, ux} from '@oclif/core'; -import cliui from 'cliui'; -import {InstanceCommand} from '@salesforce/b2c-tooling/cli'; +import {InstanceCommand, createTable, type ColumnDef} from '@salesforce/b2c-tooling/cli'; import { searchJobExecutions, type JobExecutionSearchResult, @@ -8,18 +7,7 @@ import { } from '@salesforce/b2c-tooling/operations/jobs'; import {t} from '../../i18n/index.js'; -/** - * Column definition for table output. - */ -interface ColumnDef { - header: string; - get: (e: JobExecution) => string; -} - -/** - * Available columns for job execution list output. - */ -const COLUMNS: Record = { +const COLUMNS: Record> = { id: { header: 'Execution ID', get: (e) => e.id ?? '-', @@ -124,62 +112,8 @@ export default class JobSearch extends InstanceCommand { }), ); - this.printExecutionsTable(results.hits); + createTable(COLUMNS).render(results.hits, DEFAULT_COLUMNS); return results; } - - /** - * Calculate dynamic column widths based on content. - */ - private calculateColumnWidths(executions: JobExecution[], columnKeys: string[]): Map { - const widths = new Map(); - const padding = 2; - - for (const key of columnKeys) { - const col = COLUMNS[key]; - let maxWidth = col.header.length; - - for (const exec of executions) { - const value = col.get(exec); - maxWidth = Math.max(maxWidth, value.length); - } - - widths.set(key, maxWidth + padding); - } - - return widths; - } - - private printExecutionsTable(executions: JobExecution[]): void { - const termWidth = process.stdout.columns || 120; - const ui = cliui({width: termWidth}); - const columnKeys = DEFAULT_COLUMNS; - - const widths = this.calculateColumnWidths(executions, columnKeys); - - // Header - const headerCols = columnKeys.map((key) => ({ - text: COLUMNS[key].header, - width: widths.get(key), - padding: [0, 1, 0, 0] as [number, number, number, number], - })); - ui.div(...headerCols); - - // Separator - const totalWidth = [...widths.values()].reduce((sum, w) => sum + w, 0); - ui.div({text: '─'.repeat(Math.min(totalWidth, termWidth)), padding: [0, 0, 0, 0]}); - - // Rows - for (const exec of executions) { - const rowCols = columnKeys.map((key) => ({ - text: COLUMNS[key].get(exec), - width: widths.get(key), - padding: [0, 1, 0, 0] as [number, number, number, number], - })); - ui.div(...rowCols); - } - - ux.stdout(ui.toString()); - } } diff --git a/packages/b2c-cli/src/commands/mrt/env-var/delete.ts b/packages/b2c-cli/src/commands/mrt/env-var/delete.ts new file mode 100644 index 00000000..77ab4869 --- /dev/null +++ b/packages/b2c-cli/src/commands/mrt/env-var/delete.ts @@ -0,0 +1,68 @@ +import {Args, Flags} from '@oclif/core'; +import {MrtCommand} from '@salesforce/b2c-tooling/cli'; +import {deleteEnvVar} from '@salesforce/b2c-tooling/operations/mrt'; +import {t} from '../../../i18n/index.js'; + +/** + * Delete an environment variable from an MRT project environment. + */ +export default class MrtEnvVarDelete extends MrtCommand { + static args = { + key: Args.string({ + description: 'Environment variable name', + required: true, + }), + }; + + static description = t( + 'commands.mrt.envVar.delete.description', + 'Delete an environment variable from a Managed Runtime environment', + ); + + static enableJsonFlag = true; + + static examples = [ + '<%= config.bin %> <%= command.id %> MY_VAR --project acme-storefront --environment production', + '<%= config.bin %> <%= command.id %> OLD_API_KEY -p my-project -e staging', + ]; + + static flags = { + ...MrtCommand.baseFlags, + project: Flags.string({ + char: 'p', + description: 'MRT project slug', + required: true, + }), + environment: Flags.string({ + char: 'e', + description: 'Target environment (e.g., staging, production)', + required: true, + }), + }; + + async run(): Promise<{key: string; project: string; environment: string}> { + this.requireMrtCredentials(); + + const {key} = this.args; + const {project, environment} = this.flags; + + await deleteEnvVar( + { + projectSlug: project, + environment, + key, + }, + this.getMrtAuth(), + ); + + this.log( + t('commands.mrt.envVar.delete.success', 'Deleted {{key}} from {{project}}/{{environment}}', { + key, + project, + environment, + }), + ); + + return {key, project, environment}; + } +} diff --git a/packages/b2c-cli/src/commands/mrt/env-var/list.ts b/packages/b2c-cli/src/commands/mrt/env-var/list.ts new file mode 100644 index 00000000..9d3d0785 --- /dev/null +++ b/packages/b2c-cli/src/commands/mrt/env-var/list.ts @@ -0,0 +1,88 @@ +import {Flags} from '@oclif/core'; +import {MrtCommand, createTable, type ColumnDef} from '@salesforce/b2c-tooling/cli'; +import {listEnvVars, type ListEnvVarsResult, type EnvironmentVariable} from '@salesforce/b2c-tooling/operations/mrt'; +import {t} from '../../../i18n/index.js'; + +const COLUMNS: Record> = { + name: { + header: 'Name', + get: (v) => v.name, + }, + value: { + header: 'Value', + get: (v) => v.value, + }, + status: { + header: 'Status', + get: (v) => v.publishingStatusDescription, + }, + updated: { + header: 'Updated', + get: (v) => (v.updatedAt ? new Date(v.updatedAt).toLocaleString() : '-'), + }, +}; + +const DEFAULT_COLUMNS = ['name', 'value', 'status', 'updated']; + +/** + * List environment variables on an MRT project environment. + */ +export default class MrtEnvVarList extends MrtCommand { + static description = t( + 'commands.mrt.envVar.list.description', + 'List environment variables on a Managed Runtime environment', + ); + + static enableJsonFlag = true; + + static examples = [ + '<%= config.bin %> <%= command.id %> --project acme-storefront --environment production', + '<%= config.bin %> <%= command.id %> -p my-project -e staging', + '<%= config.bin %> <%= command.id %> -p my-project -e production --json', + ]; + + static flags = { + ...MrtCommand.baseFlags, + project: Flags.string({ + char: 'p', + description: 'MRT project slug', + required: true, + }), + environment: Flags.string({ + char: 'e', + description: 'Target environment (e.g., staging, production)', + required: true, + }), + }; + + async run(): Promise { + this.requireMrtCredentials(); + + const {project, environment} = this.flags; + + this.log( + t('commands.mrt.envVar.list.fetching', 'Listing env vars for {{project}}/{{environment}}...', { + project, + environment, + }), + ); + + const result = await listEnvVars( + { + projectSlug: project, + environment, + }, + this.getMrtAuth(), + ); + + if (!this.jsonEnabled()) { + if (result.variables.length === 0) { + this.log(t('commands.mrt.envVar.list.empty', 'No environment variables found.')); + } else { + createTable(COLUMNS).render(result.variables, DEFAULT_COLUMNS); + } + } + + return result; + } +} diff --git a/packages/b2c-cli/src/commands/mrt/env-var/set.ts b/packages/b2c-cli/src/commands/mrt/env-var/set.ts index 3ffbfc53..22365a37 100644 --- a/packages/b2c-cli/src/commands/mrt/env-var/set.ts +++ b/packages/b2c-cli/src/commands/mrt/env-var/set.ts @@ -1,66 +1,107 @@ import {Args, Flags} from '@oclif/core'; import {MrtCommand} from '@salesforce/b2c-tooling/cli'; +import {setEnvVars} from '@salesforce/b2c-tooling/operations/mrt'; import {t} from '../../../i18n/index.js'; /** - * Stub command demonstrating MrtCommand usage. - * MRT operations use API key authentication. + * Set environment variables on an MRT project environment. */ export default class MrtEnvVarSet extends MrtCommand { static args = { - key: Args.string({ - description: 'Environment variable name', - required: true, - }), - value: Args.string({ - description: 'Environment variable value', + variables: Args.string({ + description: 'Environment variables in KEY=value format', required: true, }), }; static description = t( 'commands.mrt.envVar.set.description', - 'Set an environment variable on a Managed Runtime project', + 'Set environment variables on a Managed Runtime environment', ); + static enableJsonFlag = true; + static examples = [ - '<%= config.bin %> <%= command.id %> MY_VAR "my value" --project acme-storefront --environment production', + '<%= config.bin %> <%= command.id %> MY_VAR=value --project acme-storefront --environment production', + '<%= config.bin %> <%= command.id %> API_KEY=secret DEBUG=true -p my-project -e staging', + '<%= config.bin %> <%= command.id %> "MESSAGE=hello world" -p my-project -e production', ]; static flags = { + ...MrtCommand.baseFlags, project: Flags.string({ - description: 'MRT project ID', + char: 'p', + description: 'MRT project slug', required: true, }), environment: Flags.string({ char: 'e', - description: 'Target environment', + description: 'Target environment (e.g., staging, production)', required: true, }), }; - async run(): Promise { + // Allow multiple arguments + static strict = false; + + async run(): Promise<{variables: Record; project: string; environment: string}> { this.requireMrtCredentials(); - const key = this.args.key; - const value = this.args.value; - const project = this.flags.project; - const environment = this.flags.environment; + const {argv} = await this.parse(MrtEnvVarSet); + const {project, environment} = this.flags; + + // Parse KEY=value arguments + const variables: Record = {}; + const keys: string[] = []; + + for (const arg of argv as string[]) { + const eqIndex = arg.indexOf('='); + if (eqIndex === -1) { + this.error(t('commands.mrt.envVar.set.invalidFormat', 'Invalid format: {{arg}}. Use KEY=value format.', {arg})); + } + + const key = arg.slice(0, eqIndex); + const value = arg.slice(eqIndex + 1); + + if (!key) { + this.error(t('commands.mrt.envVar.set.emptyKey', 'Empty key in: {{arg}}', {arg})); + } + + variables[key] = value; + keys.push(key); + } + + if (keys.length === 0) { + this.error(t('commands.mrt.envVar.set.noVariables', 'No environment variables provided. Use KEY=value format.')); + } - this.log( - t('commands.mrt.envVar.set.setting', 'Setting {{key}} on {{project}}/{{environment}}...', { - key, - project, + await setEnvVars( + { + projectSlug: project, environment, - }), + variables, + }, + this.getMrtAuth(), ); - // TODO: Implement actual MRT API call using this.createMrtClient() + if (keys.length === 1) { + this.log( + t('commands.mrt.envVar.set.successSingle', 'Set {{key}} on {{project}}/{{environment}}', { + key: keys[0], + project, + environment, + }), + ); + } else { + this.log( + t('commands.mrt.envVar.set.successMultiple', 'Set {{count}} variables on {{project}}/{{environment}}', { + count: keys.length, + project, + environment, + }), + ); + } - this.log(''); - this.log(t('commands.mrt.envVar.set.stub', '(stub) Environment variable setting not yet implemented')); - this.log(t('commands.mrt.envVar.set.wouldSet', 'Would set {{key}}={{value}}', {key, value})); - this.log(t('commands.mrt.envVar.set.project', 'Project: {{project}}', {project})); - this.log(t('commands.mrt.envVar.set.environment', 'Environment: {{environment}}', {environment})); + return {variables, project, environment}; } } diff --git a/packages/b2c-cli/src/commands/mrt/push.ts b/packages/b2c-cli/src/commands/mrt/push.ts new file mode 100644 index 00000000..9dcb9af9 --- /dev/null +++ b/packages/b2c-cli/src/commands/mrt/push.ts @@ -0,0 +1,138 @@ +import {Flags} from '@oclif/core'; +import {MrtCommand} from '@salesforce/b2c-tooling/cli'; +import {pushBundle, DEFAULT_SSR_PARAMETERS, type PushResult} from '@salesforce/b2c-tooling/operations/mrt'; +import {t} from '../../i18n/index.js'; + +/** + * Parses SSR parameter flags into a key-value object. + * Accepts format: key=value + */ +function parseSsrParams(params: string[]): Record { + const result: Record = {}; + for (const param of params) { + const eqIndex = param.indexOf('='); + if (eqIndex === -1) { + throw new Error(`Invalid SSR parameter format: "${param}". Expected key=value format.`); + } + const key = param.slice(0, eqIndex); + const value = param.slice(eqIndex + 1); + result[key] = value; + } + return result; +} + +/** + * Push a bundle to Managed Runtime. + * + * Creates a bundle from the build directory and uploads it to the specified + * MRT project. Optionally deploys the bundle to a target environment. + */ +export default class MrtPush extends MrtCommand { + static description = t('commands.mrt.push.description', 'Push a bundle to Managed Runtime'); + + static enableJsonFlag = true; + + static examples = [ + '<%= config.bin %> <%= command.id %> --project my-storefront', + '<%= config.bin %> <%= command.id %> --project my-storefront --environment staging', + '<%= config.bin %> <%= command.id %> --project my-storefront --environment production --message "Release v1.0.0"', + '<%= config.bin %> <%= command.id %> --project my-storefront --build-dir ./dist', + '<%= config.bin %> <%= command.id %> --project my-storefront --node-version 20.x', + '<%= config.bin %> <%= command.id %> --project my-storefront --ssr-param SSRProxyPath=/api', + ]; + + static flags = { + ...MrtCommand.baseFlags, + project: Flags.string({ + char: 'p', + description: 'MRT project slug', + required: true, + }), + environment: Flags.string({ + char: 'e', + description: 'Environment to deploy to after push (e.g., staging, production)', + }), + message: Flags.string({ + char: 'm', + description: 'Bundle message/description', + }), + 'build-dir': Flags.string({ + char: 'b', + description: 'Path to the build directory', + default: 'build', + }), + 'ssr-only': Flags.string({ + description: 'Glob patterns for server-only files (comma-separated)', + default: 'ssr.js,server/**/*', + }), + 'ssr-shared': Flags.string({ + description: 'Glob patterns for shared files (comma-separated)', + default: 'static/**/*,client/**/*', + }), + 'node-version': Flags.string({ + char: 'n', + description: `Node.js version for SSR runtime (default: ${DEFAULT_SSR_PARAMETERS.SSRFunctionNodeVersion})`, + }), + 'ssr-param': Flags.string({ + description: 'SSR parameter in key=value format (can be specified multiple times)', + multiple: true, + default: [], + }), + }; + + async run(): Promise { + this.requireMrtCredentials(); + + const {project, environment: target, message} = this.flags; + const buildDir = this.flags['build-dir']; + const ssrOnly = this.flags['ssr-only'].split(',').map((s) => s.trim()); + const ssrShared = this.flags['ssr-shared'].split(',').map((s) => s.trim()); + + // Build SSR parameters from flags + const ssrParameters: Record = parseSsrParams(this.flags['ssr-param']); + + // --node-version is a convenience flag for SSRFunctionNodeVersion + if (this.flags['node-version']) { + ssrParameters.SSRFunctionNodeVersion = this.flags['node-version']; + } + + this.log(t('commands.mrt.push.pushing', 'Pushing bundle to {{project}}...', {project})); + + if (target) { + this.log(t('commands.mrt.push.willDeploy', 'Bundle will be deployed to {{environment}}', {environment: target})); + } + + try { + const result = await pushBundle( + { + projectSlug: project, + target, + message, + buildDirectory: buildDir, + ssrOnly, + ssrShared, + ssrParameters, + }, + this.getMrtAuth(), + ); + + // Consolidated success output + const deployedMsg = result.deployed && result.target ? ` and deployed to ${result.target}` : ''; + this.log( + t('commands.mrt.push.success', 'Bundle #{{bundleId}} pushed to {{project}}{{deployed}} ({{message}})', { + bundleId: String(result.bundleId), + project: result.projectSlug, + deployed: deployedMsg, + message: result.message, + }), + ); + + return result; + } catch (error) { + if (error instanceof Error) { + this.error(t('commands.mrt.push.failed', 'Push failed: {{message}}', {message: error.message})); + } + throw error; + } + } +} diff --git a/packages/b2c-cli/src/commands/ods/list.ts b/packages/b2c-cli/src/commands/ods/list.ts index 2c794fd3..016625a0 100644 --- a/packages/b2c-cli/src/commands/ods/list.ts +++ b/packages/b2c-cli/src/commands/ods/list.ts @@ -1,6 +1,5 @@ -import {Flags, ux} from '@oclif/core'; -import cliui from 'cliui'; -import {OdsCommand} from '@salesforce/b2c-tooling/cli'; +import {Flags} from '@oclif/core'; +import {OdsCommand, TableRenderer, type ColumnDef} from '@salesforce/b2c-tooling/cli'; import type {OdsComponents} from '@salesforce/b2c-tooling'; import {t} from '../../i18n/index.js'; @@ -14,24 +13,7 @@ interface OdsListResponse { data: SandboxModel[]; } -/** - * Column definition for table output. - */ -interface ColumnDef { - /** Column header label */ - header: string; - /** Minimum width in characters */ - minWidth?: number; - /** Function to extract value from sandbox */ - get: (s: SandboxModel) => string; - /** Whether this column is only shown with --extended */ - extended?: boolean; -} - -/** - * Available columns for sandbox list output. - */ -const COLUMNS: Record = { +const COLUMNS: Record> = { realm: { header: 'Realm', get: (s) => s.realm || '-', @@ -80,6 +62,8 @@ const COLUMNS: Record = { /** Default columns shown without --extended */ const DEFAULT_COLUMNS = ['realm', 'instance', 'state', 'profile', 'created', 'eol', 'id']; +const tableRenderer = new TableRenderer(COLUMNS); + /** * Command to list all on-demand sandboxes. */ @@ -176,38 +160,11 @@ export default class OdsList extends OdsCommand { return response; } - this.printSandboxesTable(sandboxes, this.getSelectedColumns()); + tableRenderer.render(sandboxes, this.getSelectedColumns()); return response; } - /** - * Calculate dynamic column widths based on content. - * Each column width = max(header length, max data length) + padding - */ - private calculateColumnWidths(sandboxes: SandboxModel[], columnKeys: string[]): Map { - const widths = new Map(); - const padding = 2; // Space between columns - - for (const key of columnKeys) { - const col = COLUMNS[key]; - // Start with header length - let maxWidth = col.header.length; - - // Check all data values - for (const sandbox of sandboxes) { - const value = col.get(sandbox); - maxWidth = Math.max(maxWidth, value.length); - } - - // Apply minimum width if specified, add padding - const minWidth = col.minWidth || 0; - widths.set(key, Math.max(maxWidth, minWidth) + padding); - } - - return widths; - } - /** * Determines which columns to display based on flags. */ @@ -218,9 +175,9 @@ export default class OdsList extends OdsCommand { if (columnsFlag) { // User specified explicit columns const requested = columnsFlag.split(',').map((c) => c.trim()); - const valid = requested.filter((c) => c in COLUMNS); + const valid = tableRenderer.validateColumnKeys(requested); if (valid.length === 0) { - this.warn(`No valid columns specified. Available: ${Object.keys(COLUMNS).join(', ')}`); + this.warn(`No valid columns specified. Available: ${tableRenderer.getColumnKeys().join(', ')}`); return DEFAULT_COLUMNS; } return valid; @@ -228,48 +185,10 @@ export default class OdsList extends OdsCommand { if (extended) { // Show all columns - return Object.keys(COLUMNS); + return tableRenderer.getColumnKeys(); } // Default columns (non-extended) return DEFAULT_COLUMNS; } - - private printSandboxesTable(sandboxes: SandboxModel[], columnKeys: string[]): void { - const termWidth = process.stdout.columns || 120; - const ui = cliui({width: termWidth}); - - // Calculate dynamic widths based on content - const widths = this.calculateColumnWidths(sandboxes, columnKeys); - - // Build header row - const headerCols = columnKeys.map((key) => { - const col = COLUMNS[key]; - return { - text: col.header, - width: widths.get(key), - padding: [0, 1, 0, 0] as [number, number, number, number], - }; - }); - ui.div(...headerCols); - - // Separator - const totalWidth = [...widths.values()].reduce((sum, w) => sum + w, 0); - ui.div({text: '─'.repeat(Math.min(totalWidth, termWidth)), padding: [0, 0, 0, 0]}); - - // Rows - for (const sandbox of sandboxes) { - const rowCols = columnKeys.map((key) => { - const col = COLUMNS[key]; - return { - text: col.get(sandbox), - width: widths.get(key), - padding: [0, 1, 0, 0] as [number, number, number, number], - }; - }); - ui.div(...rowCols); - } - - ux.stdout(ui.toString()); - } } diff --git a/packages/b2c-cli/src/commands/sites/list.ts b/packages/b2c-cli/src/commands/sites/list.ts index 1c22190c..c05adaad 100644 --- a/packages/b2c-cli/src/commands/sites/list.ts +++ b/packages/b2c-cli/src/commands/sites/list.ts @@ -1,12 +1,28 @@ import {ux} from '@oclif/core'; -import cliui from 'cliui'; -import {InstanceCommand} from '@salesforce/b2c-tooling/cli'; +import {InstanceCommand, createTable, type ColumnDef} from '@salesforce/b2c-tooling/cli'; import type {OcapiComponents} from '@salesforce/b2c-tooling'; import {t} from '../../i18n/index.js'; type Sites = OcapiComponents['schemas']['sites']; type Site = OcapiComponents['schemas']['site']; +const COLUMNS: Record> = { + id: { + header: 'ID', + get: (s) => s.id || '-', + }, + displayName: { + header: 'Display Name', + get: (s) => s.display_name?.default || s.id || '-', + }, + status: { + header: 'Status', + get: (s) => s.storefront_status || 'unknown', + }, +}; + +const DEFAULT_COLUMNS = ['id', 'displayName', 'status']; + export default class SitesList extends InstanceCommand { static description = t('commands.sites.list.description', 'List sites on a B2C Commerce instance'); @@ -46,36 +62,8 @@ export default class SitesList extends InstanceCommand { return sites; } - this.printSitesTable(sites.data ?? []); + createTable(COLUMNS).render(sites.data ?? [], DEFAULT_COLUMNS); return sites; } - - private printSitesTable(sites: Site[]): void { - const ui = cliui({width: process.stdout.columns || 80}); - - // Header - ui.div( - {text: 'ID', width: 30, padding: [0, 2, 0, 0]}, - {text: 'Display Name', width: 30, padding: [0, 2, 0, 0]}, - {text: 'Status', padding: [0, 0, 0, 0]}, - ); - - // Separator - ui.div({text: '─'.repeat(70), padding: [0, 0, 0, 0]}); - - // Rows - for (const site of sites) { - const displayName = site.display_name?.default || site.id || ''; - const status = site.storefront_status || 'unknown'; - - ui.div( - {text: site.id || '', width: 30, padding: [0, 2, 0, 0]}, - {text: displayName, width: 30, padding: [0, 2, 0, 0]}, - {text: status, padding: [0, 0, 0, 0]}, - ); - } - - ux.stdout(ui.toString()); - } } diff --git a/packages/b2c-cli/src/commands/slas/client/list.ts b/packages/b2c-cli/src/commands/slas/client/list.ts index aeeba7d3..fb7e7283 100644 --- a/packages/b2c-cli/src/commands/slas/client/list.ts +++ b/packages/b2c-cli/src/commands/slas/client/list.ts @@ -1,5 +1,4 @@ -import {ux} from '@oclif/core'; -import cliui from 'cliui'; +import {createTable, type ColumnDef} from '@salesforce/b2c-tooling/cli'; import { SlasClientCommand, type Client, @@ -13,6 +12,23 @@ interface ClientListOutput { clients: ClientOutput[]; } +const COLUMNS: Record> = { + clientId: { + header: 'Client ID', + get: (c) => c.clientId, + }, + name: { + header: 'Name', + get: (c) => c.name, + }, + isPrivate: { + header: 'Private', + get: (c) => String(c.isPrivateClient), + }, +}; + +const DEFAULT_COLUMNS = ['clientId', 'name', 'isPrivate']; + export default class SlasClientList extends SlasClientCommand { static description = t('commands.slas.client.list.description', 'List SLAS clients for a tenant'); @@ -64,33 +80,8 @@ export default class SlasClientList extends SlasClientCommand dist/cjs/package.json", @@ -137,6 +148,7 @@ "@oclif/core": "^4", "@oclif/prettier-config": "^0.2.1", "@salesforce/dev-config": "^4.3.2", + "@types/archiver": "^7.0.0", "@types/node": "^18.19.130", "eslint": "^9", "eslint-config-prettier": "^10", @@ -159,10 +171,13 @@ "node": ">=22.16.0" }, "dependencies": { + "archiver": "^7.0.1", "chokidar": "^5.0.0", + "cliui": "^9.0.1", "glob": "^13.0.0", "i18next": "^25.6.3", "jszip": "^3.10.1", + "minimatch": "^10.1.1", "open": "^11.0.0", "openapi-fetch": "^0.15.0", "pino": "^10.1.0", diff --git a/packages/b2c-tooling/specs/mrt-api-v1.json b/packages/b2c-tooling/specs/mrt-api-v1.json new file mode 100644 index 00000000..0cfb856b --- /dev/null +++ b/packages/b2c-tooling/specs/mrt-api-v1.json @@ -0,0 +1,5555 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Managed Runtime API", + "version": "v1", + "description": "Set up how a storefront or other headless commerce application is deployed to Managed Runtime.

Note: Where possible, we changed noninclusive terms to align with our company value of Equality. We maintained certain terms to avoid any effect on customer implementations." + }, + "paths": { + "/api/organizations/": { + "get": { + "operationId": "organizations_list", + "description": "List organizations.", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "description": "Number of results to return per page.", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "required": false, + "in": "query", + "description": "The initial index from which to return the results.", + "schema": { + "type": "integer" + } + } + ], + "tags": [ + "organizations" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedAPIOrganizationList" + }, + "examples": { + "ResponseExample1": { + "value": { + "count": 123, + "next": "http://api.example.org/accounts/?offset=400&limit=100", + "previous": "http://api.example.org/accounts/?offset=200&limit=100", + "results": [ + { + "uuid": "58c8da00-a596-4e62-9b93-dfc26a73528e", + "name": "my org", + "slug": "my-org", + "has_mobify_tag_project": false, + "created_at": "2020-07-14T19:33:21.197800Z", + "updated_at": "2020-07-21T17:02:38.745978Z", + "permissions": { + "browse": true, + "create_project": true, + "delete_organization": true, + "edit_organization": true + } + } + ] + } + } + } + } + }, + "description": "" + } + } + } + }, + "/api/projects/": { + "get": { + "operationId": "projects_list", + "description": "List projects.", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "description": "Number of results to return per page.", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "required": false, + "in": "query", + "description": "The initial index from which to return the results.", + "schema": { + "type": "integer" + } + }, + { + "name": "organization", + "required": false, + "in": "query", + "description": "An organization to search within.", + "schema": { + "type": "string" + } + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedAPIProjectV2CreateList" + }, + "examples": { + "ResponseExample1": { + "value": { + "count": 123, + "next": "http://api.example.org/accounts/?offset=400&limit=100", + "previous": "http://api.example.org/accounts/?offset=200&limit=100", + "results": [ + { + "name": "Progressive SSR project", + "url": "https://www.example.com/", + "slug": "project-slug", + "organization": "my-organization", + "permissions": { + "browse": true, + "deploy": true, + "delete_bundle": true, + "delete_project": true, + "edit_redirect": true, + "edit_roles": true, + "edit_settings": true, + "validate_tag": true, + "edit_environment": true, + "create_environment": true, + "delete_environment": true, + "create_notification": true, + "list_notifications": true, + "retrieve_notification": true, + "edit_notification": true, + "delete_notification": true, + "create_jwt": true, + "upload_bundle": true, + "edit_environment_variable": true, + "edit_access_control_header": true + }, + "deletion_status": "ACTIVE", + "created_at": "2025-07-24T07:30:22.288165Z", + "updated_at": "2025-07-24T08:30:22.288165Z" + } + ] + } + } + } + } + }, + "description": "" + } + } + }, + "post": { + "operationId": "projects_create", + "description": "Create a project.", + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIProjectV2Create" + }, + "examples": { + "RequestExample1": { + "value": { + "organization": "my-org", + "name": "My project", + "slug": "my-project" + } + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/APIProjectV2Create" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/APIProjectV2Create" + } + } + }, + "required": true + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIProjectV2Create" + }, + "examples": { + "ResponseExample1": { + "value": { + "name": "My project", + "url": "https://www.mobify.com", + "slug": "my-project", + "organization": "my-organization", + "permissions": { + "browse": true, + "deploy": true, + "delete_bundle": true, + "delete_project": true, + "edit_redirect": true, + "edit_roles": true, + "edit_settings": true, + "validate_tag": true, + "edit_environment": true, + "create_environment": true, + "delete_environment": true, + "create_notification": true, + "list_notifications": true, + "retrieve_notification": true, + "edit_notification": true, + "delete_notification": true, + "create_jwt": true, + "upload_bundle": true, + "edit_environment_variable": true, + "edit_access_control_header": true + }, + "deletion_status": "ACTIVE", + "created_at": "2025-07-24T07:30:22.288165Z", + "updated_at": "2025-07-24T07:30:22.288165Z" + } + } + } + } + }, + "description": "" + } + } + } + }, + "/api/projects/{project_slug}/": { + "get": { + "operationId": "projects_retrieve", + "description": "Read data about a project.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIProjectV2Update" + }, + "examples": { + "ResponseExample1": { + "value": { + "name": "test project", + "url": "https://www.google.com", + "slug": "test-project", + "organization": "my-organization", + "permissions": { + "browse": true, + "deploy": true, + "delete_bundle": true, + "delete_project": true, + "edit_redirect": true, + "edit_roles": true, + "edit_settings": true, + "validate_tag": true, + "edit_environment": true, + "create_environment": true, + "delete_environment": true, + "create_notification": true, + "list_notifications": true, + "retrieve_notification": true, + "edit_notification": true, + "delete_notification": true, + "create_jwt": true, + "upload_bundle": true, + "edit_environment_variable": true, + "edit_access_control_header": true + }, + "deletion_status": "ACTIVE", + "created_at": "2025-07-24T07:30:22.288165Z", + "updated_at": "2025-07-24T07:30:22.288165Z" + } + } + } + } + }, + "description": "" + } + } + }, + "patch": { + "operationId": "projects_partial_update", + "description": "Update a project.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PatchedAPIProjectV2Update" + }, + "examples": { + "RequestExample1": { + "value": { + "name": "new name", + "url": "https://www.mobify.com", + "organization": "my-organization" + } + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/PatchedAPIProjectV2Update" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/PatchedAPIProjectV2Update" + } + } + } + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIProjectV2Update" + }, + "examples": { + "ResponseExample1": { + "value": { + "name": "test project", + "url": "https://www.google.com", + "slug": "test-project", + "organization": "my-organization", + "permissions": { + "browse": true, + "deploy": true, + "delete_bundle": true, + "delete_project": true, + "edit_redirect": true, + "edit_roles": true, + "edit_settings": true, + "validate_tag": true, + "edit_environment": true, + "create_environment": true, + "delete_environment": true, + "create_notification": true, + "list_notifications": true, + "retrieve_notification": true, + "edit_notification": true, + "delete_notification": true, + "create_jwt": true, + "upload_bundle": true, + "edit_environment_variable": true, + "edit_access_control_header": true + }, + "deletion_status": "ACTIVE", + "created_at": "2025-07-24T07:30:22.288165Z", + "updated_at": "2025-07-24T08:30:22.288165Z" + } + } + } + } + }, + "description": "" + } + } + }, + "delete": { + "operationId": "projects_destroy", + "description": "Delete a project.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "204": { + "description": "No response body" + } + } + } + }, + "/api/projects/{project_slug}/builds/": { + "post": { + "operationId": "projects_builds_create", + "description": "Upload a bundle.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Bundle" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/Bundle" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Bundle" + } + } + }, + "required": true + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": {} + }, + "examples": { + "ResponseExample1": { + "value": { + "message": "Successfully pushed bundle for 'my-project'", + "bundle_id": 2 + } + } + } + } + }, + "description": "" + } + } + } + }, + "/api/projects/{project_slug}/builds/{target_slug}/": { + "post": { + "operationId": "projects_builds_create_and_deploy", + "description": "Upload a bundle and deploy it to an environment asynchronously.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Bundle" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/Bundle" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Bundle" + } + } + }, + "required": true + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": {} + }, + "examples": { + "ResponseExample1": { + "value": { + "message": "Successfully pushed bundle for 'my-project'", + "bundle_id": 2 + } + } + } + } + }, + "description": "" + } + } + } + }, + "/api/projects/{project_slug}/bundles/": { + "get": { + "operationId": "projects_bundles_list", + "description": "List bundles of a project", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "description": "Number of results to return per page.", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "required": false, + "in": "query", + "description": "The initial index from which to return the results.", + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "A search term.", + "schema": { + "type": "string" + } + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedBundleListList" + }, + "examples": { + "ResponseExample1": { + "value": { + "count": 123, + "next": "http://api.example.org/accounts/?offset=400&limit=100", + "previous": "http://api.example.org/accounts/?offset=200&limit=100", + "results": [ + { + "id": 3, + "message": "Bundle 2", + "status": 0, + "deletion_status": "ACTIVE", + "user": "fixture+progressive.ssr@test.com", + "created_at": "2020-05-27T22:45:35.781615Z", + "updated_at": "2020-07-09T04:59:37.733245Z", + "is_uploaded": true, + "is_ssr_bundle": true, + "ssr_runtime": "12.x", + "ssr_runtime_description": "NodeJS 12.x" + } + ] + } + }, + "ResponseExample2": { + "value": { + "count": 123, + "next": "http://api.example.org/accounts/?offset=400&limit=100", + "previous": "http://api.example.org/accounts/?offset=200&limit=100", + "results": [ + { + "id": 2, + "message": "Bundle 1", + "status": 0, + "deletion_status": "ACTIVE", + "user": "fixture+progressive.ssr@test.com", + "created_at": "2020-05-27T22:45:35.703516Z", + "updated_at": "2020-07-09T04:57:02.399510Z", + "is_uploaded": true, + "is_ssr_bundle": true, + "ssr_runtime": "10.x", + "ssr_runtime_description": "NodeJS 10.x" + } + ] + } + }, + "ResponseExample3": { + "value": { + "count": 123, + "next": "http://api.example.org/accounts/?offset=400&limit=100", + "previous": "http://api.example.org/accounts/?offset=200&limit=100", + "results": [ + { + "id": 1, + "message": "Bundle 0", + "status": 0, + "deletion_status": "ACTIVE", + "user": "fixture+progressive.ssr@test.com", + "created_at": "2020-05-27T22:45:35.646125Z", + "updated_at": "2020-07-09T06:12:19.633249Z", + "is_uploaded": true, + "is_ssr_bundle": true, + "ssr_runtime": "8.10", + "ssr_runtime_description": "NodeJS 8.10" + } + ] + } + } + } + } + }, + "description": "" + } + } + } + }, + "/api/projects/{project_slug}/bundles/{bundle_id}/download/": { + "get": { + "operationId": "projects_bundles_download_retrieve", + "description": "Get a presigned URL (active for one hour) to download a bundle archive.", + "parameters": [ + { + "in": "path", + "name": "bundle_id", + "schema": { + "type": "string" + }, + "description": "The bundle's id", + "required": true + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BundleDownload" + }, + "examples": { + "ResponseExample": { + "value": { + "download_url": "https://bundles.s3.amazonaws.com/build_archives/build_archive_id_1.tgz" + } + } + } + } + }, + "description": "" + } + } + } + }, + "/api/projects/{project_slug}/members/": { + "get": { + "operationId": "projects_members_list", + "description": "List a project's members.", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "description": "Number of results to return per page.", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "required": false, + "in": "query", + "description": "The initial index from which to return the results.", + "schema": { + "type": "integer" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Which field to use when ordering the results.", + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "query", + "name": "role", + "schema": { + "type": "integer", + "enum": [ + 0, + 1, + 2, + 3 + ] + }, + "description": "* `0` - Admin\n* `1` - Developer\n* `2` - Marketer\n* `3` - Read Only\n\n* `0` - Admin\n* `1` - Developer\n* `2` - Marketer\n* `3` - Read Only" + }, + { + "in": "path", + "name": "role", + "schema": { + "type": "string" + }, + "description": "A role to filter on. Admin=0, Developer=1, Marketer=2, Read Only=3.", + "required": true + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "A search term.", + "schema": { + "type": "string" + } + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedAPIProjectMemberList" + } + } + }, + "description": "" + } + } + }, + "post": { + "operationId": "projects_members_create", + "description": "Create a new project member.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIProjectMember" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/APIProjectMember" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/APIProjectMember" + } + } + }, + "required": true + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIProjectMember" + } + } + }, + "description": "" + } + } + } + }, + "/api/projects/{project_slug}/members/{email}/": { + "get": { + "operationId": "projects_members_retrieve", + "description": "Read data about a project member's permissions.", + "parameters": [ + { + "in": "path", + "name": "email", + "schema": { + "type": "string" + }, + "description": "The project member's email address.", + "required": true + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIProjectMember" + } + } + }, + "description": "" + } + } + }, + "patch": { + "operationId": "projects_members_partial_update", + "description": "Update a project member's permissions.", + "parameters": [ + { + "in": "path", + "name": "email", + "schema": { + "type": "string" + }, + "description": "The project member's email address.", + "required": true + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PatchedAPIProjectMember" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/PatchedAPIProjectMember" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/PatchedAPIProjectMember" + } + } + } + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIProjectMember" + } + } + }, + "description": "" + } + } + }, + "delete": { + "operationId": "projects_members_destroy", + "description": "Delete a project member.", + "parameters": [ + { + "in": "path", + "name": "email", + "schema": { + "type": "string" + }, + "description": "The project member's email address.", + "required": true + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "204": { + "description": "No response body" + } + } + } + }, + "/api/projects/{project_slug}/notifications/": { + "get": { + "operationId": "projects_notifications_list", + "description": "List notifications for a project", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "description": "Number of results to return per page.", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "required": false, + "in": "query", + "description": "The initial index from which to return the results.", + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "query", + "name": "targets__slug", + "schema": { + "type": "string" + } + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedPolymorphicNotificationList" + } + } + }, + "description": "" + } + } + }, + "post": { + "operationId": "projects_notifications_create", + "description": "Create notification for a Project", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PolymorphicNotification" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/PolymorphicNotification" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/PolymorphicNotification" + } + } + } + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PolymorphicNotification" + } + } + }, + "description": "" + } + } + } + }, + "/api/projects/{project_slug}/notifications/{id}/": { + "get": { + "operationId": "projects_notifications_retrieve", + "description": "Read data about a notification.", + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string" + }, + "description": "The notification's unique UUID", + "required": true + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PolymorphicNotification" + } + } + }, + "description": "" + } + } + }, + "patch": { + "operationId": "projects_notifications_partial_update", + "description": "Update a project's notification.", + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string" + }, + "description": "The notification's unique UUID", + "required": true + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PatchedPolymorphicNotification" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/PatchedPolymorphicNotification" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/PatchedPolymorphicNotification" + } + } + } + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PolymorphicNotification" + } + } + }, + "description": "" + } + } + }, + "delete": { + "operationId": "projects_notifications_destroy", + "description": "Delete a notification.", + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string" + }, + "description": "The notification's unique UUID", + "required": true + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "204": { + "description": "No response body" + } + } + } + }, + "/api/projects/{project_slug}/target/": { + "get": { + "operationId": "projects_target_list", + "description": "List a project's targets.", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "description": "Number of results to return per page.", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "required": false, + "in": "query", + "description": "The initial index from which to return the results.", + "schema": { + "type": "integer" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Which field to use when ordering the results.", + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "A search term.", + "schema": { + "type": "string" + } + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedAPITargetV2CreateList" + }, + "examples": { + "ResponseExample1": { + "value": { + "count": 123, + "next": "http://api.example.org/accounts/?offset=400&limit=100", + "previous": "http://api.example.org/accounts/?offset=200&limit=100", + "results": [ + { + "slug": "production", + "name": "Production", + "state": "CREATE_IN_PROGRESS", + "deletion_status": "ACTIVE", + "hostname": null, + "current_deploy": { + "status": "queued", + "is_ssr_deploy": false, + "updated_at": "2018-07-25T21:35:24.312882+00:00", + "bundle": { + "status": 0, + "deletion_status": "ACTIVE", + "api_bundle_preview_email_url": "/api/projects/project-slug/bundle/0/preview-email/", + "go_preview_url": null, + "updated_at": "2018-07-25T21:35:24.311809+00:00", + "app_preview_url": null, + "message": "Reset Bundle. Disables adaptation.", + "id": 0, + "is_uploaded": true, + "created_at": "2018-07-25T21:35:24.311775+00:00", + "preview_url": null, + "is_ssr_bundle": false, + "user_email": "" + }, + "is_in_progress": true, + "deploy_settings": null, + "deploy_type": "reset_bundle", + "created_at": "2018-07-25T21:35:24.312855+00:00", + "deploy_duration": 778590.636166, + "applied_deploy_settings": false, + "status_message": "Queueing Bundle" + }, + "ssr_external_hostname": "www-testing.example.com", + "ssr_external_domain": "example.com", + "ssr_region": "eu-central-1", + "ssr_whitelisted_ips": "103.12.25.0/24", + "ssr_proxy_configs": [ + { + "host": "www.proxyhost1.com", + "protocol": "https" + }, + { + "host": "www.proxyhost2.com" + } + ], + "allow_cookies": false, + "enable_source_maps": false, + "log_level": "INFO" + } + ] + } + } + } + } + }, + "description": "" + } + } + }, + "post": { + "operationId": "projects_target_create", + "description": "Create a new target.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APITargetV2Create" + }, + "examples": { + "RequestExample1": { + "value": { + "name": "Testing EU", + "slug": "testing-eu", + "ssr_external_hostname": "www-testing.example.com", + "ssr_external_domain": "example.com", + "ssr_region": "eu-central-1", + "ssr_whitelisted_ips": "103.12.25.0/24", + "ssr_proxy_configs": [ + { + "host": "www.proxyhost1.com", + "protocol": "https" + }, + { + "host": "www.proxyhost2.com" + } + ], + "allow_cookies": false, + "enable_source_maps": false, + "log_level": "INFO" + } + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/APITargetV2Create" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/APITargetV2Create" + } + } + }, + "required": true + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APITargetV2Create" + }, + "examples": { + "ResponseExample1": { + "value": { + "name": "Testing EU", + "slug": "testing-eu", + "ssr_external_hostname": "www-testing.example.com", + "ssr_external_domain": "example.com", + "ssr_region": "eu-central-1", + "ssr_whitelisted_ips": "103.12.25.0/24", + "ssr_proxy_configs": [ + { + "host": "www.proxyhost1.com", + "protocol": "https" + }, + { + "host": "www.proxyhost2.com" + } + ], + "allow_cookies": true, + "enable_source_maps": false, + "log_level": "INFO" + } + } + } + } + }, + "description": "" + } + } + } + }, + "/api/projects/{project_slug}/target/{target_slug}/": { + "get": { + "operationId": "projects_target_retrieve", + "description": "Read data about a target.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APITargetV2Update" + }, + "examples": { + "ResponseExample1": { + "value": { + "slug": "ssr-target-successful", + "name": "Testing EU", + "state": "ACTIVE", + "deletion_status": "ACTIVE", + "hostname": "www0.somewhere.com", + "current_deploy": { + "status": "queued", + "is_ssr_deploy": true, + "updated_at": "2018-08-10T16:54:38.871068+00:00", + "bundle": { + "status": 0, + "deletion_status": "ACTIVE", + "api_bundle_preview_email_url": "/api/projects/project-slug/bundle/2/preview-email/", + "go_preview_url": null, + "updated_at": "2018-07-25T21:35:24.801637+00:00", + "app_preview_url": null, + "description": "NodeJS 16.x", + "ssr_runtime_state": "available", + "message": "SSR Bundle 1 (failed deploy 81)", + "id": 2, + "is_uploaded": true, + "created_at": "2018-07-25T21:35:24.762928+00:00", + "preview_url": null, + "is_ssr_bundle": true, + "user_email": "fixture+progressive.ssr@test.com" + }, + "external_publish_id": "None", + "external_progress_update": null, + "external_progress_percentage": null, + "is_in_progress": true, + "deploy_settings": null, + "external_progress_status": null, + "deploy_type": "publish", + "created_at": "2018-08-10T16:54:38.871027+00:00", + "deploy_duration": 2.356207, + "external_progress_message": null, + "applied_deploy_settings": false, + "status_message": "Queueing Bundle", + "user_email": "fixture+tag.page.staff@test.com", + "external_progress_description": null + }, + "ssr_external_hostname": "www-testing.example.com", + "ssr_external_domain": "example.com", + "ssr_region": "eu-central-1", + "ssr_whitelisted_ips": "103.12.25.0/24", + "ssr_proxy_configs": [ + { + "host": "www.proxyhost1.com", + "protocol": "http" + }, + { + "host": "www.proxyhost2.com", + "protocol": "https" + } + ], + "allow_cookies": false, + "enable_source_maps": false, + "log_level": "INFO" + } + } + } + } + }, + "description": "" + } + } + }, + "patch": { + "operationId": "projects_target_partial_update", + "description": "Update a target. Important: This endpoint automatically re-deploys the current bundle if any of the SSR-related properties are changed.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PatchedAPITargetV2Update" + }, + "examples": { + "RequestExample1": { + "value": { + "name": "Testing EU", + "ssr_external_hostname": "www-testing.example.com", + "ssr_external_domain": "example.com", + "ssr_region": "eu-central-1", + "ssr_whitelisted_ips": "103.12.25.0/24", + "ssr_proxy_configs": [ + { + "host": "www.proxyhost1.com", + "protocol": "http" + }, + { + "host": "www.proxyhost2.com", + "protocol": "https" + } + ], + "allow_cookies": true, + "enable_source_maps": true, + "log_level": "INFO" + } + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/PatchedAPITargetV2Update" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/PatchedAPITargetV2Update" + } + } + } + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APITargetV2Update" + }, + "examples": { + "ResponseExample1": { + "value": { + "slug": "ssr-target-successful", + "name": "Testing EU", + "state": "ACTIVE", + "deletion_status": "ACTIVE", + "hostname": "www0.somewhere.com", + "current_deploy": { + "status": "queued", + "is_ssr_deploy": true, + "updated_at": "2018-08-10T16:54:38.871068+00:00", + "bundle": { + "status": 0, + "deletion_status": "ACTIVE", + "api_bundle_preview_email_url": "/api/projects/project-slug/bundle/2/preview-email/", + "go_preview_url": null, + "updated_at": "2018-07-25T21:35:24.801637+00:00", + "app_preview_url": null, + "message": "SSR Bundle 1 (failed deploy 81)", + "id": 2, + "is_uploaded": true, + "created_at": "2018-07-25T21:35:24.762928+00:00", + "preview_url": null, + "is_ssr_bundle": true, + "user_email": "fixture+progressive.ssr@test.com" + }, + "external_publish_id": "None", + "external_progress_update": null, + "external_progress_percentage": null, + "is_in_progress": true, + "deploy_settings": null, + "external_progress_status": null, + "deploy_type": "publish", + "created_at": "2018-08-10T16:54:38.871027+00:00", + "deploy_duration": 2.356207, + "external_progress_message": null, + "applied_deploy_settings": false, + "status_message": "Queueing Bundle", + "user_email": "fixture+tag.page.staff@test.com", + "external_progress_description": null + }, + "ssr_external_hostname": "www-testing.example.com", + "ssr_external_domain": "example.com", + "ssr_region": "eu-central-1", + "ssr_whitelisted_ips": "103.12.25.0/24", + "ssr_proxy_configs": [ + { + "host": "www.proxyhost1.com", + "protocol": "http" + }, + { + "host": "www.proxyhost2.com", + "protocol": "https" + } + ], + "allow_cookies": true, + "enable_source_maps": true, + "log_level": "INFO" + } + } + } + } + }, + "description": "" + } + } + }, + "delete": { + "operationId": "projects_target_destroy", + "description": "Delete a target.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "204": { + "description": "No response body" + } + } + } + }, + "/api/projects/{project_slug}/target/{target_slug}/access-control-header/": { + "get": { + "operationId": "projects_target_access_control_header_list", + "description": "List a target's access control headers.", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "description": "Number of results to return per page.", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "required": false, + "in": "query", + "description": "The initial index from which to return the results.", + "schema": { + "type": "integer" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Which field to use when ordering the results.", + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "A search term.", + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedAPIAccessControlHeaderV2CreateList" + }, + "examples": { + "ResponseExample1": { + "value": { + "count": 123, + "next": "http://api.example.org/accounts/?offset=400&limit=100", + "previous": "http://api.example.org/accounts/?offset=200&limit=100", + "results": [ + { + "id": "ff832a9e-0e55-11ef-8f23-0242ac110002", + "value": "****************by0z", + "user_email": "jane.doe@mobify.com", + "created_at": "2024-04-28T09:23:28.872916Z", + "publishing_status": 0, + "publishing_status_description": "Pending" + } + ] + } + } + } + } + }, + "description": "" + } + } + }, + "post": { + "operationId": "projects_target_access_control_header_create", + "description": "Create an access control header to restrict access to an environment so that only trusted traffic coming from your content delivery network (CDN) or development team is allowed. Requests to this environment must contain the header `x-sfdc-access-control` with the value provided or they will be rejected. Accepts an object with a value for a single access control header. See [Access Control Headers](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html?q=access%20control%20header#access-control-headers).", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIAccessControlHeaderV2Create" + }, + "examples": { + "RequestExample1": { + "value": { + "value": "jfoWikeaby0z" + } + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/APIAccessControlHeaderV2Create" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/APIAccessControlHeaderV2Create" + } + } + }, + "required": true + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIAccessControlHeaderV2Create" + }, + "examples": { + "ResponseExample1": { + "value": { + "id": "ff832a9e-0e55-11ef-8f23-0242ac110002", + "value": "****************by0z", + "user_email": "jane.doe@mobify.com", + "created_at": "2024-04-28T09:23:28.872916Z", + "publishing_status": 0, + "publishing_status_description": "Pending" + } + } + } + } + }, + "description": "" + } + } + } + }, + "/api/projects/{project_slug}/target/{target_slug}/access-control-header/{id}/": { + "get": { + "operationId": "projects_target_access_control_header_retrieve", + "description": "Read data about an access control header by its id.", + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string" + }, + "description": "The access control header's id.", + "required": true + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIAccessControlHeaderV2Create" + }, + "examples": { + "ResponseExample1": { + "value": { + "id": "ff832a9e-0e55-11ef-8f23-0242ac110002", + "value": "****************by0z", + "user_email": "jane.doe@mobify.com", + "created_at": "2024-04-28T09:23:28.872916Z", + "publishing_status": 0, + "publishing_status_description": "Pending" + } + } + } + } + }, + "description": "" + } + } + }, + "delete": { + "operationId": "projects_target_access_control_header_destroy", + "description": "Delete an access control header by its id.", + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string" + }, + "description": "The access control header's id.", + "required": true + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "204": { + "description": "No response body" + } + } + } + }, + "/api/projects/{project_slug}/target/{target_slug}/deploy/": { + "get": { + "operationId": "projects_target_deploy_list", + "description": "Get the deployment history of a target.", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "description": "Number of results to return per page.", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "required": false, + "in": "query", + "description": "The initial index from which to return the results.", + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedDeployListList" + }, + "examples": { + "ResponseExample1": { + "value": { + "count": 123, + "next": "http://api.example.org/accounts/?offset=400&limit=100", + "previous": "http://api.example.org/accounts/?offset=200&limit=100", + "results": [ + { + "user": "fixture+progressive.ssr@test.com", + "duration": "00:01:16.867967", + "bundle": { + "id": 2, + "message": "Bundle 1 (failed deploy 242)", + "status": 0, + "deletion_status": "ACTIVE", + "user": "fixture+progressive.ssr@test.com", + "created_at": "2020-10-13T23:09:39.309698Z", + "updated_at": "2020-10-13T23:09:39.344068Z", + "is_uploaded": true, + "is_ssr_bundle": true, + "ssr_runtime": "10.x", + "ssr_runtime_description": "NodeJS 10.x" + }, + "created_at": "2020-10-14T23:36:35.238529Z", + "updated_at": "2020-10-15T00:14:34.227033Z", + "status": "Finished", + "deploy_type": "Publish", + "external_publish_id": "b035a4d7-ec6b-4dcd-af8f-3a847b10fed8", + "deploy_settings": null + } + ] + } + }, + "ResponseExample2": { + "value": { + "count": 123, + "next": "http://api.example.org/accounts/?offset=400&limit=100", + "previous": "http://api.example.org/accounts/?offset=200&limit=100", + "results": [ + { + "user": "fixture+progressive.ssr@test.com", + "duration": "00:01:16.867967", + "bundle": { + "id": 1, + "message": "Reset Bundle. Disables adaptation.", + "status": 0, + "deletion_status": "ACTIVE", + "user": null, + "created_at": "2020-10-13T23:09:39.285998Z", + "updated_at": "2020-10-13T23:09:39.286030Z", + "is_uploaded": true, + "is_ssr_bundle": false, + "ssr_runtime": null, + "ssr_runtime_description": null + }, + "created_at": "2020-10-14T23:26:44.018200Z", + "updated_at": "2020-10-14T23:36:26.168594Z", + "status": "Finished", + "deploy_type": "Reset Bundle", + "external_publish_id": "b035a4d7-ec6b-4dcd-af8f-3a847b10fed8", + "deploy_settings": null + } + ] + } + } + } + } + }, + "description": "" + } + } + }, + "post": { + "operationId": "projects_target_deploy_create", + "description": "Deploys a bundle to a target. Returns the status of the deploy. Deployment details are not immediately available in the response as this endpoint is asynchronous. Request the target for progress updates.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeployCreate" + }, + "examples": { + "RequestExample1": { + "value": { + "bundle_id": "22" + } + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/DeployCreate" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/DeployCreate" + } + } + }, + "required": true + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeployCreate" + }, + "examples": { + "ResponseExample1": { + "value": { + "status": "queued", + "is_ssr_deploy": true, + "updated_at": "2019-10-09T19:43:04.108157+00:00", + "bundle_id": 3, + "bundle": { + "status": 0, + "deletion_status": "ACTIVE", + "api_bundle_preview_email_url": "/api/projects/project-slug/bundle/3/preview-email/", + "go_preview_url": null, + "updated_at": "2019-10-09T17:31:00.418509+00:00", + "app_preview_url": null, + "message": "SSR Bundle 2 (running deploy 83)", + "id": 3, + "is_uploaded": true, + "created_at": "2019-10-09T17:31:00.383617+00:00", + "preview_url": null, + "is_ssr_bundle": true, + "user_email": "fixture+progressive.ssr@test.com" + }, + "external_publish_id": "None", + "external_progress_update": null, + "external_progress_percentage": null, + "is_in_progress": true, + "deploy_settings": null, + "external_progress_status": null, + "deploy_type": "publish", + "created_at": "2019-10-09T19:43:04.108107+00:00", + "deploy_duration": 0.305502, + "external_progress_message": null, + "external_publish_details": {}, + "applied_deploy_settings": false, + "status_message": "Queueing Bundle", + "user_email": "fixture+progressive.ssr@test.com", + "external_progress_description": null + } + } + } + } + }, + "description": "" + } + } + } + }, + "/api/projects/{project_slug}/target/{target_slug}/env-var/": { + "get": { + "operationId": "projects_target_env_var_list", + "description": "List a target's environment variables.", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "description": "Number of results to return per page.", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "required": false, + "in": "query", + "description": "The initial index from which to return the results.", + "schema": { + "type": "integer" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Which field to use when ordering the results.", + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "A search term.", + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedEnvironmentVariableListList" + }, + "examples": { + "ResponseExample1": { + "value": { + "count": 123, + "next": "http://api.example.org/accounts/?offset=400&limit=100", + "previous": "http://api.example.org/accounts/?offset=200&limit=100", + "results": [ + { + "SUPER_SECRET_API_KEY": { + "value": "****************6dIR", + "created_by": "john.doe@mobify.com", + "created_at": "2020-02-26T18:05:28.873516Z", + "updated_at": "2020-02-26T18:05:35.625877Z", + "updated_by": "john.doe@mobify.com", + "publishing_status": 0, + "publishing_status_description": "Pending" + } + } + ] + } + } + } + } + }, + "description": "" + } + } + }, + "patch": { + "operationId": "projects_target_env_var_partial_update", + "description": "Create, update, or delete environment variables. Accepts an object with values for single or multiple environment variables. If the variable does not exist, it is created. If the variable exists, it is updated. And if the variable exists and the value is null, it is deleted.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": {} + }, + "examples": { + "RequestExample1": { + "value": { + "CREATE-ENV-VAR": { + "value": "new-value" + }, + "UPDATE-ENV-VAR": { + "value": "updated-value" + }, + "DELETE-ENV-VAR": { + "value": null + } + } + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "type": "object", + "additionalProperties": {} + } + }, + "multipart/form-data": { + "schema": { + "type": "object", + "additionalProperties": {} + } + } + } + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "204": { + "description": "No response body. The request was processed successfully." + } + } + } + }, + "/api/projects/{project_slug}/target/{target_slug}/invalidation/": { + "post": { + "operationId": "projects_target_invalidation_create", + "description": "Invalidate a target's cached objects in the CDN. Cache invalidations are asynchronous and usually complete within two minutes.", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APITargetV2CreateInvalidation" + }, + "examples": { + "RequestExample1": { + "value": { + "pattern": "/path/to/products/*/" + } + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/APITargetV2CreateInvalidation" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/APITargetV2CreateInvalidation" + } + } + }, + "required": true + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APITargetV2CreateInvalidation" + }, + "examples": { + "ResponseExample1": { + "value": { + "result": "Cache invalidation is in progress.", + "slug": "testing-eu" + } + } + } + } + }, + "description": "" + } + } + } + }, + "/api/projects/{project_slug}/target/{target_slug}/redirect/": { + "get": { + "operationId": "projects_target_redirect_list", + "description": "List a target's redirects. See [Redirects](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#redirects).", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "description": "Number of results to return per page.", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "required": false, + "in": "query", + "description": "The initial index from which to return the results.", + "schema": { + "type": "integer" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Which field to use when ordering the results.", + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "A search term.", + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedAPIRedirectV2CreateUpdateList" + }, + "examples": { + "ResponseExample1": { + "value": { + "count": 123, + "next": "http://api.example.org/accounts/?offset=400&limit=100", + "previous": "http://api.example.org/accounts/?offset=200&limit=100", + "results": [ + { + "from_path": "/spring", + "to_url": "/summer", + "forward_querystring": false, + "http_status_code": 301, + "publishing_status": "Pending", + "user_email": "john.doe@mobify.com", + "updated_by": "john.doe@mobify.com", + "created_at": "2020-02-26T18:05:28.873516Z", + "updated_at": "2020-02-26T18:05:35.625877Z" + } + ] + } + } + } + } + }, + "description": "" + } + } + }, + "post": { + "operationId": "projects_target_redirect_create", + "description": "Create one or more redirects. This endpoint accepts either an object with values for a single redirect, or an array of objects for bulk creation. For example, consider a seasonal campaign page for spring. When the spring campaign ends and is replaced with a summer campaign, you can redirect from the spring URL to the summer URL. We recommend that you always create redirects in your staging target (environment) and then [clone](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-admin?meta=projects_target_redirect_clone_create) them to your production target. This allows you to test the redirects and verify that they work as expected. Changes may take up to 20 minutes to take effect on your site. See [Redirects](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#redirects).", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIRedirectV2CreateUpdate" + }, + "examples": { + "RequestExample1-BulkRedirectCreation": { + "value": [ + { + "from_path": "/spring/category1", + "to_url": "/summer/category1", + "forward_querystring": false, + "forward_wildcard": true + }, + { + "from_path": "/spring/category2", + "to_url": "/summer/category2", + "forward_querystring": false, + "forward_wildcard": true + }, + { + "from_path": "/spring/category3", + "to_url": "/summer/category3", + "forward_querystring": false, + "forward_wildcard": true + } + ], + "summary": "RequestExample1 - Bulk Redirect Creation" + }, + "RequestExample2-SingleRedirectCreation": { + "value": { + "from_path": "/spring/*", + "to_url": "/summer", + "forward_querystring": false, + "forward_wildcard": true + }, + "summary": "RequestExample2 - Single Redirect Creation" + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/APIRedirectV2CreateUpdate" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/APIRedirectV2CreateUpdate" + } + } + }, + "required": true + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIRedirectV2CreateUpdate" + }, + "examples": { + "ResponseExample1-BulkRedirectCreation": { + "value": "// No response body. The request was processed successfully.", + "summary": "ResponseExample1 - Bulk Redirect Creation" + }, + "ResponseExample2-SingleRedirectCreation": { + "value": { + "from_path": "/spring/*", + "to_url": "/summer", + "forward_querystring": false, + "forward_wildcard": true, + "http_status_code": 301, + "publishing_status": "Pending", + "user_email": "john.doe@example.com", + "updated_by": "john.doe@example.com", + "created_at": "2024-05-23T00:00:00.000Z", + "updated_at": "2024-05-23T00:00:00.000Z" + }, + "summary": "ResponseExample2 - Single Redirect Creation" + } + } + } + }, + "description": "The request was processed successfully." + } + } + } + }, + "/api/projects/{project_slug}/target/{target_slug}/redirect/{from_path}": { + "get": { + "operationId": "projects_target_redirect_retrieve", + "description": "Read data about a redirect by `from_path`. See [Redirects](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#redirects).", + "parameters": [ + { + "in": "path", + "name": "from_path", + "schema": { + "type": "string" + }, + "description": "The redirect's `from_path`.", + "required": true + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIRedirectV2CreateUpdate" + } + } + }, + "description": "" + } + } + }, + "patch": { + "operationId": "projects_target_redirect_partial_update", + "description": "Update a redirect by `from_path`. For example, you can change a redirect if your content moved or you rebranded with new pages. We recommend that you always change redirects in your staging target (environment), and then [clone](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-admin?meta=projects_target_redirect_clone_create) the changes to your production target. Changes may take up to 20 minutes to take effect on your site. See [Redirects](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#redirects).", + "parameters": [ + { + "in": "path", + "name": "from_path", + "schema": { + "type": "string" + }, + "description": "The redirect's `from_path`.", + "required": true + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PatchedAPIRedirectV2CreateUpdate" + }, + "examples": { + "RequestExample1": { + "value": { + "from_path": "/spring", + "to_url": "/summer-newbranding", + "http_status_code": 301 + } + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/PatchedAPIRedirectV2CreateUpdate" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/PatchedAPIRedirectV2CreateUpdate" + } + } + } + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIRedirectV2CreateUpdate" + }, + "examples": { + "ResponseExample1": { + "value": { + "from_path": "/spring", + "to_url": "/summer-newbranding", + "http_status_code": 301, + "publishing_status": "Pending", + "user_email": "john.doe@example.com", + "updated_by": "john.doe@example.com", + "created_at": "2024-05-23T00:00:00.000Z", + "updated_at": "2024-05-23T00:00:00.000Z" + } + } + } + } + }, + "description": "The request was processed successfully." + } + } + }, + "delete": { + "operationId": "projects_target_redirect_destroy", + "description": "Delete a redirect by `from_path`. For example, you can delete a redirect that's no longer needed because a seasonal campaign is over, you removed a page, or you want to streamline your redirect structure and improve search engine ranking. We recommend that you always delete redirects in your staging target (environment), and then [clone](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-admin?meta=projects_target_redirect_clone_create) the changes to your production target. Changes may take up to 20 minutes to take effect on your site. When you delete a redirect, you no longer see it in Runtime Admin. See [Redirects](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#redirects).", + "parameters": [ + { + "in": "path", + "name": "from_path", + "schema": { + "type": "string" + }, + "description": "The redirect's `from_path`.", + "required": true + }, + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "target_slug", + "schema": { + "type": "string" + }, + "description": "The target identifier.", + "required": true + } + ], + "tags": [ + "projects" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "204": { + "description": "No response body. The request was processed successfully." + } + } + } + }, + "/api/projects/{project_slug}/target/{to_target_slug}/redirect/clone/": { + "post": { + "operationId": "projects_target_redirect_clone_create", + "description": "Clone redirects from one target to another. Important: when you clone redirects, you're replacing all the redirects in one target with all the redirects in the other. See [Redirects](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#redirects).", + "parameters": [ + { + "in": "path", + "name": "project_slug", + "schema": { + "type": "string" + }, + "description": "The project identifier.", + "required": true + }, + { + "in": "path", + "name": "to_target_slug", + "schema": { + "type": "string" + }, + "description": "The destination target identifier for the clone operation.", + "required": true + } + ], + "tags": [ + "projects" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIRedirectV2Clone" + }, + "examples": { + "RequestExample1": { + "value": { + "from_target_slug": "staging" + } + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/APIRedirectV2Clone" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/APIRedirectV2Clone" + } + } + }, + "required": true + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIRedirectV2Clone" + } + } + }, + "description": "" + } + } + } + }, + "/api/users/me/api_key/": { + "post": { + "operationId": "users_me_api_key_create", + "description": "Generate or reset the API key.", + "tags": [ + "users" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": {} + }, + "examples": { + "ResponseExample1": { + "value": { + "api_key": "qLh_IRpIh594lPeURV4giczpW0q-Ki0YIcOdDz0aw0g" + } + } + } + } + }, + "description": "" + } + } + } + }, + "/api/users/me/email-preferences/": { + "get": { + "operationId": "users_me_email_preferences_retrieve", + "description": "Get email notification preferences for the authenticated user.", + "tags": [ + "users" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserEmailPreferences" + }, + "examples": { + "ResponseExample1": { + "value": { + "node_deprecation_notifications": true, + "created_at": "2024-01-15T10:30:00Z", + "updated_at": "2024-01-15T10:30:00Z" + } + } + } + } + }, + "description": "" + } + } + }, + "patch": { + "operationId": "users_me_email_preferences_partial_update", + "description": "Update email notification preferences for the authenticated user.", + "tags": [ + "users" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PatchedUserEmailPreferences" + }, + "examples": { + "RequestExample1": { + "value": { + "node_deprecation_notifications": false + } + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/PatchedUserEmailPreferences" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/PatchedUserEmailPreferences" + } + } + } + }, + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserEmailPreferences" + }, + "examples": { + "ResponseExample1": { + "value": { + "node_deprecation_notifications": false, + "created_at": "2024-01-15T10:30:00Z", + "updated_at": "2024-01-15T10:35:00Z" + } + } + } + } + }, + "description": "" + } + } + } + }, + "/api/users/me/profile/": { + "get": { + "operationId": "users_me_profile_retrieve", + "description": "Get the profile information for the authenticated user.", + "tags": [ + "users" + ], + "security": [ + { + "Basic": [] + }, + { + "BearerToken": [] + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIUserProfile" + }, + "examples": { + "ResponseExample1": { + "value": { + "firstname": "thomas", + "lastname": "berko", + "email": "thomas.berko@example.com" + } + } + } + } + }, + "description": "" + } + } + } + } + }, + "components": { + "schemas": { + "APIAccessControlHeaderV2Create": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true, + "description": "Id for this Access Control Header." + }, + "value": { + "type": "string", + "description": "Value to be encrypted. A header value is made up of your chosen set of characters. For the constraints that apply to the value, see [Access Control Headers](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html?q=access%20control%20header#access-control-headers)." + }, + "user_email": { + "type": "string", + "format": "email", + "title": "Email address", + "readOnly": true + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "publishing_status": { + "allOf": [ + { + "$ref": "#/components/schemas/PublishingStatusEnum" + } + ], + "readOnly": true + }, + "publishing_status_description": { + "type": "string", + "readOnly": true + } + }, + "required": [ + "value" + ] + }, + "APIOrganization": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "name": { + "type": "string", + "maxLength": 128 + }, + "slug": { + "type": "string", + "maxLength": 64, + "pattern": "^[a-z0-9]+(?:-+[a-z0-9]+)*$" + }, + "deletion_status": { + "allOf": [ + { + "$ref": "#/components/schemas/DeletionStatusEnum" + } + ], + "readOnly": true + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + }, + "permissions": { + "type": "object", + "properties": { + "create_project": { + "type": "boolean" + } + }, + "readOnly": true + }, + "has_mobify_tag_project": { + "type": "boolean", + "readOnly": true + }, + "limits": { + "allOf": [ + { + "$ref": "#/components/schemas/OrganizationLimits" + } + ], + "readOnly": true + }, + "auto_delete": { + "allOf": [ + { + "$ref": "#/components/schemas/OrganizationAutoDelete" + } + ], + "readOnly": true + } + }, + "required": [ + "name", + "slug" + ] + }, + "APIProjectMember": { + "type": "object", + "properties": { + "user": { + "type": "string", + "format": "email", + "title": "Email address" + }, + "role": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "enum": [ + 0, + 1, + 2, + 3 + ], + "type": "integer" + } + } + } + }, + "required": [ + "role", + "user" + ] + }, + "APIProjectV2Create": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "User-friendly name for this project", + "maxLength": 64 + }, + "url": { + "type": "string", + "format": "uri", + "maxLength": 2000 + }, + "slug": { + "type": "string", + "maxLength": 20, + "pattern": "^[a-z0-9]+(?:-+[a-z0-9]+)*$" + }, + "organization": { + "type": "string", + "description": "User-friendly identifier for this instance." + }, + "deletion_status": { + "allOf": [ + { + "$ref": "#/components/schemas/DeletionStatusEnum" + } + ], + "readOnly": true + }, + "project_type": { + "allOf": [ + { + "$ref": "#/components/schemas/ProjectTypeEnum" + } + ], + "readOnly": true + }, + "permissions": { + "type": "object", + "properties": { + "browse": { + "type": "boolean" + }, + "deploy": { + "type": "boolean" + }, + "delete_bundle": { + "type": "boolean" + }, + "delete_project": { + "type": "boolean" + }, + "edit_redirect": { + "type": "boolean" + }, + "edit_roles": { + "type": "boolean" + }, + "edit_settings": { + "type": "boolean" + }, + "validate_tag": { + "type": "boolean" + }, + "edit_environment": { + "type": "boolean" + }, + "create_environment": { + "type": "boolean" + }, + "delete_environment": { + "type": "boolean" + }, + "create_notification": { + "type": "boolean" + }, + "list_notifications": { + "type": "boolean" + }, + "retrieve_notification": { + "type": "boolean" + }, + "edit_notification": { + "type": "boolean" + }, + "delete_notification": { + "type": "boolean" + }, + "create_jwt": { + "type": "boolean" + }, + "upload_bundle": { + "type": "boolean" + }, + "edit_environment_variable": { + "type": "boolean" + }, + "edit_access_control_header": { + "type": "boolean" + } + }, + "readOnly": true + }, + "ssr_region": { + "allOf": [ + { + "$ref": "#/components/schemas/SsrRegionEnum" + } + ], + "title": "SSR AWS Region", + "description": "The default AWS region for newly created targets\n\n* `us-east-1` - US East (N. Virginia)\n* `us-east-2` - US East (Ohio)\n* `us-west-1` - US West (N. California)\n* `us-west-2` - US West (Oregon)\n* `ap-south-1` - Asia Pacific (Mumbai)\n* `ap-south-2` - Asia Pacific (Hyderabad)\n* `ap-northeast-2` - Asia Pacific (Seoul)\n* `ap-southeast-1` - Asia Pacific (Singapore)\n* `ap-southeast-2` - Asia Pacific (Sydney)\n* `ap-southeast-3` - Asia Pacific (Jakarta)\n* `ap-northeast-1` - Asia Pacific (Tokyo)\n* `ap-northeast-3` - Asia Pacific (Osaka)\n* `ca-central-1` - Canada (Central)\n* `eu-central-1` - EU (Frankfurt)\n* `eu-central-2` - EU (Zurich)\n* `eu-west-1` - EU (Ireland)\n* `eu-west-2` - EU (London)\n* `eu-west-3` - EU (Paris)\n* `eu-north-1` - EU (Stockholm)\n* `eu-south-1` - EU (Milan)\n* `il-central-1` - Israel (Tel Aviv)\n* `me-central-1` - Middle East (UAE)\n* `sa-east-1` - South America (Sao Paulo)" + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + } + }, + "required": [ + "name", + "organization" + ] + }, + "APIProjectV2Update": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "User-friendly name for this project", + "maxLength": 64 + }, + "url": { + "type": "string", + "format": "uri", + "maxLength": 2000 + }, + "slug": { + "type": "string", + "readOnly": true, + "pattern": "^[-a-zA-Z0-9_]+$" + }, + "organization": { + "type": "string", + "description": "User-friendly identifier for this instance." + }, + "deletion_status": { + "allOf": [ + { + "$ref": "#/components/schemas/DeletionStatusEnum" + } + ], + "readOnly": true + }, + "project_type": { + "allOf": [ + { + "$ref": "#/components/schemas/ProjectTypeEnum" + } + ], + "readOnly": true + }, + "permissions": { + "type": "object", + "properties": { + "browse": { + "type": "boolean" + }, + "deploy": { + "type": "boolean" + }, + "delete_bundle": { + "type": "boolean" + }, + "delete_project": { + "type": "boolean" + }, + "edit_redirect": { + "type": "boolean" + }, + "edit_roles": { + "type": "boolean" + }, + "edit_settings": { + "type": "boolean" + }, + "validate_tag": { + "type": "boolean" + }, + "edit_environment": { + "type": "boolean" + }, + "create_environment": { + "type": "boolean" + }, + "delete_environment": { + "type": "boolean" + }, + "create_notification": { + "type": "boolean" + }, + "list_notifications": { + "type": "boolean" + }, + "retrieve_notification": { + "type": "boolean" + }, + "edit_notification": { + "type": "boolean" + }, + "delete_notification": { + "type": "boolean" + }, + "create_jwt": { + "type": "boolean" + }, + "upload_bundle": { + "type": "boolean" + }, + "edit_environment_variable": { + "type": "boolean" + }, + "edit_access_control_header": { + "type": "boolean" + } + }, + "readOnly": true + }, + "ssr_region": { + "allOf": [ + { + "$ref": "#/components/schemas/SsrRegionEnum" + } + ], + "title": "SSR AWS Region", + "description": "The default AWS region for newly created targets\n\n* `us-east-1` - US East (N. Virginia)\n* `us-east-2` - US East (Ohio)\n* `us-west-1` - US West (N. California)\n* `us-west-2` - US West (Oregon)\n* `ap-south-1` - Asia Pacific (Mumbai)\n* `ap-south-2` - Asia Pacific (Hyderabad)\n* `ap-northeast-2` - Asia Pacific (Seoul)\n* `ap-southeast-1` - Asia Pacific (Singapore)\n* `ap-southeast-2` - Asia Pacific (Sydney)\n* `ap-southeast-3` - Asia Pacific (Jakarta)\n* `ap-northeast-1` - Asia Pacific (Tokyo)\n* `ap-northeast-3` - Asia Pacific (Osaka)\n* `ca-central-1` - Canada (Central)\n* `eu-central-1` - EU (Frankfurt)\n* `eu-central-2` - EU (Zurich)\n* `eu-west-1` - EU (Ireland)\n* `eu-west-2` - EU (London)\n* `eu-west-3` - EU (Paris)\n* `eu-north-1` - EU (Stockholm)\n* `eu-south-1` - EU (Milan)\n* `il-central-1` - Israel (Tel Aviv)\n* `me-central-1` - Middle East (UAE)\n* `sa-east-1` - South America (Sao Paulo)" + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + } + }, + "required": [ + "name" + ] + }, + "APIRedirectV2Clone": { + "type": "object", + "properties": { + "from_target_slug": { + "type": "string", + "pattern": "^[-a-zA-Z0-9_]+$" + } + }, + "required": [ + "from_target_slug" + ] + }, + "APIRedirectV2CreateUpdate": { + "type": "object", + "properties": { + "from_path": { + "type": "string", + "description": "A relative URL. For example, the `from_path` value `/spring` redirects shoppers from the URL `www.example.com/spring`. An asterisk (`*`) at the end of the `from_path` indicates a wildcard. For example, a redirect from `/a/*` matches `/a/`, `/a/b`, and `/a/b/c`.", + "maxLength": 2000 + }, + "to_url": { + "type": "string", + "description": "A relative or absolute URL. For example, the `to_url` value `/summer` redirects shoppers to the URL `www.example.com/summer`.", + "maxLength": 2000 + }, + "forward_querystring": { + "type": "boolean", + "nullable": true, + "description": "Some requests contain query string parameters to include in the redirected request. For example, the relative path `/spring-landing-page` can be appended with a query string for analytics tracking, such as `/spring-landing-page?gclid=123`. The `true` value includes query string parameters in the redirect. The `false` value excludes query string parameters from the redirect. The default value is `false`." + }, + "forward_wildcard": { + "type": "boolean", + "nullable": true, + "description": "The `true` value automatically includes any path that comes after the wildcard portion of the `from_path` in the `to_url`. For example: if `/a/*` matches `/a/b/c` in the `from_path` and the `to_url` is `/z/`, the redirect URL is `/z/b/c`. The `false` value excludes the wildcard portion. The default value is `false`. " + }, + "http_status_code": { + "allOf": [ + { + "$ref": "#/components/schemas/HttpStatusCodeEnum" + } + ], + "description": "The HTTP status code to be returned in the response. 301 (Moved Permanently) is the recommended and default value. 302 (Found or Moved Temporarily) is another allowable value. For more information about HTTP status codes, see this [status code explainer](https://moz.com/learn/seo/redirection).\n\n* `301` - Permanent 301\n* `302` - Temporary 302" + }, + "publishing_status": { + "type": "string", + "readOnly": true, + "description": "The status of the redeployment that happens after you call this API. Allowable values: Pending, Completed, Failed. If the request failed, you can [redeploy the environment](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/pushing-and-deploying-bundles.html) specified in your request." + }, + "user_email": { + "type": "string", + "format": "email", + "title": "Email address", + "readOnly": true, + "description": "Email of the user who created the redirect." + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + }, + "updated_by": { + "type": "string", + "format": "email", + "title": "Email address", + "readOnly": true, + "description": "Email of the user who last updated the redirect." + } + }, + "required": [ + "from_path", + "to_url" + ] + }, + "APITargetV2Create": { + "type": "object", + "description": "This is the serializer for target create/list APIs.", + "properties": { + "slug": { + "type": "string", + "maxLength": 64, + "pattern": "^[a-z0-9]+(?:-+[a-z0-9]+)*$" + }, + "name": { + "type": "string", + "description": "User-friendly name for this target", + "maxLength": 64 + }, + "state": { + "allOf": [ + { + "$ref": "#/components/schemas/StateEnum" + } + ], + "readOnly": true, + "description": "Target State\n\n* `CREATE_IN_PROGRESS` - Create in Progress\n* `PUBLISH_IN_PROGRESS` - Publish in Progress\n* `ACTIVE` - Active\n* `CREATE_FAILED` - Create Failed\n* `PUBLISH_FAILED` - Publish Failed" + }, + "deletion_status": { + "allOf": [ + { + "$ref": "#/components/schemas/DeletionStatusEnum" + } + ], + "readOnly": true + }, + "hostname": { + "type": "string", + "nullable": true, + "description": "Hostname (literal or JavaScript regular expression between / characters) on which this target should be loaded by the V8 Tag", + "maxLength": 128 + }, + "current_deploy": { + "type": "object", + "additionalProperties": {}, + "readOnly": true + }, + "ssr_external_hostname": { + "type": "string", + "nullable": true, + "description": "Full hostname to used by the environment eg. www.customer.com.", + "maxLength": 128 + }, + "ssr_external_domain": { + "type": "string", + "nullable": true, + "description": "The domain to be used for a Universal PWA SSR deployment (e.g. customer.com)", + "maxLength": 128 + }, + "ssr_region": { + "title": "SSR AWS Region", + "description": "The AWS region to which a Universal PWA SSR should be deployed (e.g. us-east-1)\n\n* `us-east-1` - US East (N. Virginia)\n* `us-east-2` - US East (Ohio)\n* `us-west-1` - US West (N. California)\n* `us-west-2` - US West (Oregon)\n* `ap-south-1` - Asia Pacific (Mumbai)\n* `ap-south-2` - Asia Pacific (Hyderabad)\n* `ap-northeast-2` - Asia Pacific (Seoul)\n* `ap-southeast-1` - Asia Pacific (Singapore)\n* `ap-southeast-2` - Asia Pacific (Sydney)\n* `ap-southeast-3` - Asia Pacific (Jakarta)\n* `ap-northeast-1` - Asia Pacific (Tokyo)\n* `ap-northeast-3` - Asia Pacific (Osaka)\n* `ca-central-1` - Canada (Central)\n* `eu-central-1` - EU (Frankfurt)\n* `eu-central-2` - EU (Zurich)\n* `eu-west-1` - EU (Ireland)\n* `eu-west-2` - EU (London)\n* `eu-west-3` - EU (Paris)\n* `eu-north-1` - EU (Stockholm)\n* `eu-south-1` - EU (Milan)\n* `il-central-1` - Israel (Tel Aviv)\n* `me-central-1` - Middle East (UAE)\n* `sa-east-1` - South America (Sao Paulo)", + "oneOf": [ + { + "$ref": "#/components/schemas/SsrRegionEnum" + }, + { + "$ref": "#/components/schemas/BlankEnum" + } + ] + }, + "ssr_whitelisted_ips": { + "type": "string", + "nullable": true, + "description": "Optional space-separated list of IP addresses (CIDR blocks) that can access this target. Leave blank to allow all IPs." + }, + "ssr_proxy_configs": { + "type": "array", + "nullable": true, + "items": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "protocol": { + "type": "string" + } + }, + "required": [ + "host" + ] + } + }, + "is_production": { + "type": "boolean", + "title": "Production", + "description": "Treat this target as a production environment." + }, + "allow_cookies": { + "type": "boolean", + "nullable": true, + "description": "Set true to forward the HTTP cookie header sent by clients to your origin and ensure the Set-Cookie header sent by your app is respected and not stripped." + }, + "enable_source_maps": { + "type": "boolean", + "nullable": true, + "description": "Set true to enable source map support. This will set the NODE_OPTIONS environment variable to \"--enable-source-maps\" in your MRT environment." + }, + "log_level": { + "nullable": true, + "description": "The minimum log level emitted for this target.n\n* `TRACE`\n* `DEBUG`\n* `INFO`\n* `WARN`\n* `ERROR`\n* `FATAL`", + "oneOf": [ + { + "$ref": "#/components/schemas/LogLevelEnum" + }, + { + "$ref": "#/components/schemas/NullEnum" + } + ] + } + }, + "required": [ + "name" + ] + }, + "APITargetV2CreateInvalidation": { + "type": "object", + "description": "This is the serializer for cache invalidation API endpoint.", + "properties": { + "pattern": { + "type": "string", + "description": "Path pattern to invalidate on the CDN. This must start with a forward slash (`/`)." + }, + "items": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "default": [], + "description": "[Deprecated] Items to invalidate in the application cache.", + "maxItems": 50000, + "deprecated": true + }, + "namespace": { + "type": "string", + "description": "[Deprecated] Namespace of items to invalidate in the application cache.", + "deprecated": true + } + }, + "required": [ + "pattern" + ] + }, + "APITargetV2Update": { + "type": "object", + "description": "This is the base Target serializer.", + "properties": { + "slug": { + "type": "string", + "readOnly": true, + "pattern": "^[-a-zA-Z0-9_]+$" + }, + "name": { + "type": "string", + "description": "User-friendly name for this target", + "maxLength": 64 + }, + "state": { + "allOf": [ + { + "$ref": "#/components/schemas/StateEnum" + } + ], + "readOnly": true, + "description": "Target State\n\n* `CREATE_IN_PROGRESS` - Create in Progress\n* `PUBLISH_IN_PROGRESS` - Publish in Progress\n* `ACTIVE` - Active\n* `CREATE_FAILED` - Create Failed\n* `PUBLISH_FAILED` - Publish Failed" + }, + "deletion_status": { + "allOf": [ + { + "$ref": "#/components/schemas/DeletionStatusEnum" + } + ], + "readOnly": true + }, + "hostname": { + "type": "string", + "nullable": true, + "description": "Hostname (literal or JavaScript regular expression between / characters) on which this target should be loaded by the V8 Tag", + "maxLength": 128 + }, + "current_deploy": { + "type": "object", + "additionalProperties": {}, + "readOnly": true + }, + "ssr_external_hostname": { + "type": "string", + "nullable": true, + "description": "Full hostname to used by the environment eg. www.customer.com.", + "maxLength": 128 + }, + "ssr_external_domain": { + "type": "string", + "nullable": true, + "description": "The domain to be used for a Universal PWA SSR deployment (e.g. customer.com)", + "maxLength": 128 + }, + "ssr_region": { + "title": "SSR AWS Region", + "description": "The AWS region to which a Universal PWA SSR should be deployed (e.g. us-east-1)\n\n* `us-east-1` - US East (N. Virginia)\n* `us-east-2` - US East (Ohio)\n* `us-west-1` - US West (N. California)\n* `us-west-2` - US West (Oregon)\n* `ap-south-1` - Asia Pacific (Mumbai)\n* `ap-south-2` - Asia Pacific (Hyderabad)\n* `ap-northeast-2` - Asia Pacific (Seoul)\n* `ap-southeast-1` - Asia Pacific (Singapore)\n* `ap-southeast-2` - Asia Pacific (Sydney)\n* `ap-southeast-3` - Asia Pacific (Jakarta)\n* `ap-northeast-1` - Asia Pacific (Tokyo)\n* `ap-northeast-3` - Asia Pacific (Osaka)\n* `ca-central-1` - Canada (Central)\n* `eu-central-1` - EU (Frankfurt)\n* `eu-central-2` - EU (Zurich)\n* `eu-west-1` - EU (Ireland)\n* `eu-west-2` - EU (London)\n* `eu-west-3` - EU (Paris)\n* `eu-north-1` - EU (Stockholm)\n* `eu-south-1` - EU (Milan)\n* `il-central-1` - Israel (Tel Aviv)\n* `me-central-1` - Middle East (UAE)\n* `sa-east-1` - South America (Sao Paulo)", + "oneOf": [ + { + "$ref": "#/components/schemas/SsrRegionEnum" + }, + { + "$ref": "#/components/schemas/BlankEnum" + } + ] + }, + "ssr_whitelisted_ips": { + "type": "string", + "nullable": true, + "description": "Optional space-separated list of IP addresses (CIDR blocks) that can access this target. Leave blank to allow all IPs." + }, + "ssr_proxy_configs": { + "type": "array", + "nullable": true, + "items": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "protocol": { + "type": "string" + } + }, + "required": [ + "host" + ] + } + }, + "is_production": { + "type": "boolean", + "title": "Production", + "description": "Treat this target as a production environment." + }, + "allow_cookies": { + "type": "boolean", + "nullable": true, + "description": "Set true to forward the HTTP cookie header sent by clients to your origin and ensure the Set-Cookie header sent by your app is respected and not stripped." + }, + "enable_source_maps": { + "type": "boolean", + "nullable": true, + "description": "Set true to enable source map support. This will set the NODE_OPTIONS environment variable to \"--enable-source-maps\" in your MRT environment." + }, + "log_level": { + "nullable": true, + "description": "The minimum log level emitted for this target.n\n* `TRACE`\n* `DEBUG`\n* `INFO`\n* `WARN`\n* `ERROR`\n* `FATAL`", + "oneOf": [ + { + "$ref": "#/components/schemas/LogLevelEnum" + }, + { + "$ref": "#/components/schemas/NullEnum" + } + ] + } + }, + "required": [ + "name" + ] + }, + "APIUserProfile": { + "type": "object", + "properties": { + "first_name": { + "type": "string", + "maxLength": 255 + }, + "last_name": { + "type": "string", + "maxLength": 255 + }, + "email": { + "type": "string", + "format": "email", + "readOnly": true, + "title": "Email address" + }, + "is_staff": { + "type": "boolean", + "readOnly": true, + "title": "Staff status", + "description": "Designates whether the user can log into this admin site." + }, + "date_joined": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "uuid": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "highest_account_manager_role": { + "type": "string", + "readOnly": true + } + } + }, + "BlankEnum": { + "enum": [ + "" + ] + }, + "Bundle": { + "type": "object", + "description": "Serializer to validate a bundle upload payload.", + "properties": { + "message": { + "type": "string", + "maxLength": 2048 + }, + "data": { + "type": "string" + }, + "encoding": { + "$ref": "#/components/schemas/EncodingEnum" + }, + "ssr_only": { + "type": "array", + "items": { + "type": "string" + } + }, + "ssr_shared": { + "type": "array", + "items": { + "type": "string" + } + }, + "ssr_parameters": { + "type": "object", + "additionalProperties": {} + }, + "bundle_metadata": { + "type": "object", + "additionalProperties": {} + } + }, + "required": [ + "data", + "encoding", + "message" + ] + }, + "BundleDownload": { + "type": "object", + "properties": { + "download_url": { + "type": "string", + "format": "uri" + } + }, + "required": [ + "download_url" + ] + }, + "BundleList": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "maximum": 2147483647, + "minimum": 0, + "description": "A ID unique within a project." + }, + "message": { + "type": "string", + "maxLength": 2048 + }, + "status": { + "allOf": [ + { + "$ref": "#/components/schemas/Status1d2Enum" + } + ], + "minimum": -2147483648, + "maximum": 2147483647 + }, + "deletion_status": { + "$ref": "#/components/schemas/DeletionStatusEnum" + }, + "user": { + "type": "string", + "format": "email", + "title": "Email address", + "readOnly": true + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + } + }, + "required": [ + "id", + "message" + ] + }, + "DeletionStatusEnum": { + "enum": [ + "ACTIVE", + "CLEANUP_REQUESTED", + "CLEANUP_IN_PROGRESS", + "CLEANUP_COMPLETE", + "CLEANUP_FAILED" + ], + "type": "string", + "description": "* `ACTIVE` - Active\n* `CLEANUP_REQUESTED` - Cleanup Requested\n* `CLEANUP_IN_PROGRESS` - Cleanup in Progress\n* `CLEANUP_COMPLETE` - Cleanup Complete\n* `CLEANUP_FAILED` - Cleanup Failed" + }, + "DeployCreate": { + "type": "object", + "description": "This is the serializer for create deploy API endpoint.", + "properties": { + "bundle_id": { + "description": "Integer ID of the bundle to deploy or the string `current`, which re-deploys the currently deployed bundle" + } + }, + "required": [ + "bundle_id" + ] + }, + "DeployList": { + "type": "object", + "properties": { + "user": { + "type": "string", + "format": "email", + "title": "Email address", + "readOnly": true + }, + "bundle": { + "$ref": "#/components/schemas/BundleList" + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + }, + "status": { + "allOf": [ + { + "$ref": "#/components/schemas/DeployListStatusEnum" + } + ], + "readOnly": true + }, + "deploy_type": { + "allOf": [ + { + "$ref": "#/components/schemas/DeployTypeEnum" + } + ], + "readOnly": true + }, + "external_publish_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "Id for an external publishing operation for this Deploy" + }, + "deploy_settings": { + "type": "integer", + "nullable": true + }, + "duration": { + "type": "string" + } + }, + "required": [ + "bundle", + "duration" + ] + }, + "DeployListStatusEnum": { + "enum": [ + "Queued", + "In Progress", + "Failed", + "Finished" + ], + "type": "string", + "description": "* `Queued` - Queued\n* `In Progress` - In Progress\n* `Failed` - Failed\n* `Finished` - Finished" + }, + "DeployTypeEnum": { + "enum": [ + "Publish", + "Reset Bundle", + "Push", + "Deploy Settings", + "Redeploy" + ], + "type": "string", + "description": "* `Publish` - Publish\n* `Reset Bundle` - Reset Bundle\n* `Push` - Push\n* `Deploy Settings` - Deploy Settings\n* `Redeploy` - Redeploy" + }, + "EmailNotification": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "targets": { + "type": "array", + "items": { + "type": "string", + "description": "User-friendly identifier for this target." + } + }, + "recipients": { + "type": "array", + "items": { + "type": "string", + "format": "email", + "maxLength": 254 + } + }, + "deployment_start": { + "type": "boolean", + "description": "Trigger this notification when a deployment starts for a target" + }, + "deployment_success": { + "type": "boolean", + "description": "Trigger this notification when a deployment succeeds for a target" + }, + "deployment_failed": { + "type": "boolean", + "description": "Trigger this notification when a deployment fails for a target" + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + }, + "updated_by": { + "type": "string", + "format": "email", + "title": "Email address", + "readOnly": true + } + }, + "required": [ + "recipients", + "targets" + ] + }, + "EmailNotificationTyped": { + "allOf": [ + { + "type": "object", + "properties": { + "resourcetype": { + "type": "string" + } + }, + "required": [ + "resourcetype" + ] + }, + { + "$ref": "#/components/schemas/EmailNotification" + } + ] + }, + "EncodingEnum": { + "enum": [ + "base64" + ], + "type": "string", + "description": "* `base64` - base64" + }, + "EnvironmentVariableList": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the Environment Variable.", + "maxLength": 512 + }, + "value": { + "type": "string", + "description": "Value to be encrypted." + }, + "created_by": { + "type": "string", + "format": "email", + "title": "Email address", + "readOnly": true + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + }, + "updated_by": { + "type": "string", + "format": "email", + "title": "Email address", + "readOnly": true + }, + "publishing_status": { + "allOf": [ + { + "$ref": "#/components/schemas/PublishingStatusEnum" + } + ], + "readOnly": true + }, + "publishing_status_description": { + "type": "string", + "readOnly": true + } + }, + "required": [ + "name", + "value" + ] + }, + "HttpStatusCodeEnum": { + "enum": [ + 301, + 302 + ], + "type": "integer", + "description": "* `301` - Permanent 301\n* `302` - Temporary 302" + }, + "LogLevelEnum": { + "enum": [ + "TRACE", + "DEBUG", + "INFO", + "WARN", + "ERROR", + "FATAL" + ], + "type": "string", + "description": "The minimum log level emitted for a target." + }, + "NullEnum": { + "enum": [ + null + ] + }, + "OrganizationAutoDelete": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "threshold": { + "type": "integer" + } + }, + "required": [ + "enabled", + "threshold" + ] + }, + "OrganizationLimits": { + "type": "object", + "properties": { + "max_environments": { + "$ref": "#/components/schemas/ResourceLimit" + }, + "max_production_environments": { + "$ref": "#/components/schemas/ResourceLimit" + } + }, + "required": [ + "max_environments", + "max_production_environments" + ] + }, + "PaginatedAPIAccessControlHeaderV2CreateList": { + "type": "object", + "required": [ + "count", + "results" + ], + "properties": { + "count": { + "type": "integer", + "example": 123 + }, + "next": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=400&limit=100" + }, + "previous": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=200&limit=100" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/APIAccessControlHeaderV2Create" + } + } + } + }, + "PaginatedAPIOrganizationList": { + "type": "object", + "required": [ + "count", + "results" + ], + "properties": { + "count": { + "type": "integer", + "example": 123 + }, + "next": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=400&limit=100" + }, + "previous": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=200&limit=100" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/APIOrganization" + } + } + } + }, + "PaginatedAPIProjectMemberList": { + "type": "object", + "required": [ + "count", + "results" + ], + "properties": { + "count": { + "type": "integer", + "example": 123 + }, + "next": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=400&limit=100" + }, + "previous": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=200&limit=100" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/APIProjectMember" + } + } + } + }, + "PaginatedAPIProjectV2CreateList": { + "type": "object", + "required": [ + "count", + "results" + ], + "properties": { + "count": { + "type": "integer", + "example": 123 + }, + "next": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=400&limit=100" + }, + "previous": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=200&limit=100" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/APIProjectV2Create" + } + } + } + }, + "PaginatedAPIRedirectV2CreateUpdateList": { + "type": "object", + "required": [ + "count", + "results" + ], + "properties": { + "count": { + "type": "integer", + "example": 123 + }, + "next": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=400&limit=100" + }, + "previous": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=200&limit=100" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/APIRedirectV2CreateUpdate" + } + } + } + }, + "PaginatedAPITargetV2CreateList": { + "type": "object", + "required": [ + "count", + "results" + ], + "properties": { + "count": { + "type": "integer", + "example": 123 + }, + "next": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=400&limit=100" + }, + "previous": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=200&limit=100" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/APITargetV2Create" + } + } + } + }, + "PaginatedBundleListList": { + "type": "object", + "required": [ + "count", + "results" + ], + "properties": { + "count": { + "type": "integer", + "example": 123 + }, + "next": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=400&limit=100" + }, + "previous": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=200&limit=100" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BundleList" + } + } + } + }, + "PaginatedDeployListList": { + "type": "object", + "required": [ + "count", + "results" + ], + "properties": { + "count": { + "type": "integer", + "example": 123 + }, + "next": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=400&limit=100" + }, + "previous": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=200&limit=100" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DeployList" + } + } + } + }, + "PaginatedEnvironmentVariableListList": { + "type": "object", + "required": [ + "count", + "results" + ], + "properties": { + "count": { + "type": "integer", + "example": 123 + }, + "next": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=400&limit=100" + }, + "previous": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=200&limit=100" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnvironmentVariableList" + } + } + } + }, + "PaginatedPolymorphicNotificationList": { + "type": "object", + "required": [ + "count", + "results" + ], + "properties": { + "count": { + "type": "integer", + "example": 123 + }, + "next": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=400&limit=100" + }, + "previous": { + "type": "string", + "nullable": true, + "format": "uri", + "example": "http://api.example.org/accounts/?offset=200&limit=100" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PolymorphicNotification" + } + } + } + }, + "PatchedAPIProjectMember": { + "type": "object", + "properties": { + "user": { + "type": "string", + "format": "email", + "title": "Email address" + }, + "role": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "enum": [ + 0, + 1, + 2, + 3 + ], + "type": "integer" + } + } + } + } + }, + "PatchedAPIProjectV2Update": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "User-friendly name for this project", + "maxLength": 64 + }, + "url": { + "type": "string", + "format": "uri", + "maxLength": 2000 + }, + "slug": { + "type": "string", + "readOnly": true, + "pattern": "^[-a-zA-Z0-9_]+$" + }, + "organization": { + "type": "string", + "description": "User-friendly identifier for this instance." + }, + "deletion_status": { + "allOf": [ + { + "$ref": "#/components/schemas/DeletionStatusEnum" + } + ], + "readOnly": true + }, + "project_type": { + "allOf": [ + { + "$ref": "#/components/schemas/ProjectTypeEnum" + } + ], + "readOnly": true + }, + "permissions": { + "type": "object", + "properties": { + "browse": { + "type": "boolean" + }, + "deploy": { + "type": "boolean" + }, + "delete_bundle": { + "type": "boolean" + }, + "delete_project": { + "type": "boolean" + }, + "edit_redirect": { + "type": "boolean" + }, + "edit_roles": { + "type": "boolean" + }, + "edit_settings": { + "type": "boolean" + }, + "validate_tag": { + "type": "boolean" + }, + "edit_environment": { + "type": "boolean" + }, + "create_environment": { + "type": "boolean" + }, + "delete_environment": { + "type": "boolean" + }, + "create_notification": { + "type": "boolean" + }, + "list_notifications": { + "type": "boolean" + }, + "retrieve_notification": { + "type": "boolean" + }, + "edit_notification": { + "type": "boolean" + }, + "delete_notification": { + "type": "boolean" + }, + "create_jwt": { + "type": "boolean" + }, + "upload_bundle": { + "type": "boolean" + }, + "edit_environment_variable": { + "type": "boolean" + }, + "edit_access_control_header": { + "type": "boolean" + } + }, + "readOnly": true + }, + "ssr_region": { + "allOf": [ + { + "$ref": "#/components/schemas/SsrRegionEnum" + } + ], + "title": "SSR AWS Region", + "description": "The default AWS region for newly created targets\n\n* `us-east-1` - US East (N. Virginia)\n* `us-east-2` - US East (Ohio)\n* `us-west-1` - US West (N. California)\n* `us-west-2` - US West (Oregon)\n* `ap-south-1` - Asia Pacific (Mumbai)\n* `ap-south-2` - Asia Pacific (Hyderabad)\n* `ap-northeast-2` - Asia Pacific (Seoul)\n* `ap-southeast-1` - Asia Pacific (Singapore)\n* `ap-southeast-2` - Asia Pacific (Sydney)\n* `ap-southeast-3` - Asia Pacific (Jakarta)\n* `ap-northeast-1` - Asia Pacific (Tokyo)\n* `ap-northeast-3` - Asia Pacific (Osaka)\n* `ca-central-1` - Canada (Central)\n* `eu-central-1` - EU (Frankfurt)\n* `eu-central-2` - EU (Zurich)\n* `eu-west-1` - EU (Ireland)\n* `eu-west-2` - EU (London)\n* `eu-west-3` - EU (Paris)\n* `eu-north-1` - EU (Stockholm)\n* `eu-south-1` - EU (Milan)\n* `il-central-1` - Israel (Tel Aviv)\n* `me-central-1` - Middle East (UAE)\n* `sa-east-1` - South America (Sao Paulo)" + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + } + } + }, + "PatchedAPIRedirectV2CreateUpdate": { + "type": "object", + "properties": { + "from_path": { + "type": "string", + "description": "A relative URL. For example, the `from_path` value `/spring` redirects shoppers from the URL `www.example.com/spring`. An asterisk (`*`) at the end of the `from_path` indicates a wildcard. For example, a redirect from `/a/*` matches `/a/`, `/a/b`, and `/a/b/c`.", + "maxLength": 2000 + }, + "to_url": { + "type": "string", + "description": "A relative or absolute URL. For example, the `to_url` value `/summer` redirects shoppers to the URL `www.example.com/summer`.", + "maxLength": 2000 + }, + "forward_querystring": { + "type": "boolean", + "nullable": true, + "description": "Some requests contain query string parameters to include in the redirected request. For example, the relative path `/spring-landing-page` can be appended with a query string for analytics tracking, such as `/spring-landing-page?gclid=123`. The `true` value includes query string parameters in the redirect. The `false` value excludes query string parameters from the redirect. The default value is `false`." + }, + "forward_wildcard": { + "type": "boolean", + "nullable": true, + "description": "The `true` value automatically includes any path that comes after the wildcard portion of the `from_path` in the `to_url`. For example: if `/a/*` matches `/a/b/c` in the `from_path` and the `to_url` is `/z/`, the redirect URL is `/z/b/c`. The `false` value excludes the wildcard portion. The default value is `false`. " + }, + "http_status_code": { + "allOf": [ + { + "$ref": "#/components/schemas/HttpStatusCodeEnum" + } + ], + "description": "The HTTP status code to be returned in the response. 301 (Moved Permanently) is the recommended and default value. 302 (Found or Moved Temporarily) is another allowable value. For more information about HTTP status codes, see this [status code explainer](https://moz.com/learn/seo/redirection).\n\n* `301` - Permanent 301\n* `302` - Temporary 302" + }, + "publishing_status": { + "type": "string", + "readOnly": true, + "description": "The status of the redeployment that happens after you call this API. Allowable values: Pending, Completed, Failed. If the request failed, you can [redeploy the environment](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/pushing-and-deploying-bundles.html) specified in your request." + }, + "user_email": { + "type": "string", + "format": "email", + "title": "Email address", + "readOnly": true, + "description": "Email of the user who created the redirect." + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + }, + "updated_by": { + "type": "string", + "format": "email", + "title": "Email address", + "readOnly": true, + "description": "Email of the user who last updated the redirect." + } + } + }, + "PatchedAPITargetV2Update": { + "type": "object", + "description": "This is the base Target serializer.", + "properties": { + "slug": { + "type": "string", + "readOnly": true, + "pattern": "^[-a-zA-Z0-9_]+$" + }, + "name": { + "type": "string", + "description": "User-friendly name for this target", + "maxLength": 64 + }, + "state": { + "allOf": [ + { + "$ref": "#/components/schemas/StateEnum" + } + ], + "readOnly": true, + "description": "Target State\n\n* `CREATE_IN_PROGRESS` - Create in Progress\n* `PUBLISH_IN_PROGRESS` - Publish in Progress\n* `ACTIVE` - Active\n* `CREATE_FAILED` - Create Failed\n* `PUBLISH_FAILED` - Publish Failed" + }, + "deletion_status": { + "allOf": [ + { + "$ref": "#/components/schemas/DeletionStatusEnum" + } + ], + "readOnly": true + }, + "hostname": { + "type": "string", + "nullable": true, + "description": "Hostname (literal or JavaScript regular expression between / characters) on which this target should be loaded by the V8 Tag", + "maxLength": 128 + }, + "current_deploy": { + "type": "object", + "additionalProperties": {}, + "readOnly": true + }, + "ssr_external_hostname": { + "type": "string", + "nullable": true, + "description": "Full hostname to used by the environment eg. www.customer.com.", + "maxLength": 128 + }, + "ssr_external_domain": { + "type": "string", + "nullable": true, + "description": "The domain to be used for a Universal PWA SSR deployment (e.g. customer.com)", + "maxLength": 128 + }, + "ssr_region": { + "title": "SSR AWS Region", + "description": "The AWS region to which a Universal PWA SSR should be deployed (e.g. us-east-1)\n\n* `us-east-1` - US East (N. Virginia)\n* `us-east-2` - US East (Ohio)\n* `us-west-1` - US West (N. California)\n* `us-west-2` - US West (Oregon)\n* `ap-south-1` - Asia Pacific (Mumbai)\n* `ap-south-2` - Asia Pacific (Hyderabad)\n* `ap-northeast-2` - Asia Pacific (Seoul)\n* `ap-southeast-1` - Asia Pacific (Singapore)\n* `ap-southeast-2` - Asia Pacific (Sydney)\n* `ap-southeast-3` - Asia Pacific (Jakarta)\n* `ap-northeast-1` - Asia Pacific (Tokyo)\n* `ap-northeast-3` - Asia Pacific (Osaka)\n* `ca-central-1` - Canada (Central)\n* `eu-central-1` - EU (Frankfurt)\n* `eu-central-2` - EU (Zurich)\n* `eu-west-1` - EU (Ireland)\n* `eu-west-2` - EU (London)\n* `eu-west-3` - EU (Paris)\n* `eu-north-1` - EU (Stockholm)\n* `eu-south-1` - EU (Milan)\n* `il-central-1` - Israel (Tel Aviv)\n* `me-central-1` - Middle East (UAE)\n* `sa-east-1` - South America (Sao Paulo)", + "oneOf": [ + { + "$ref": "#/components/schemas/SsrRegionEnum" + }, + { + "$ref": "#/components/schemas/BlankEnum" + } + ] + }, + "ssr_whitelisted_ips": { + "type": "string", + "nullable": true, + "description": "Optional space-separated list of IP addresses (CIDR blocks) that can access this target. Leave blank to allow all IPs." + }, + "ssr_proxy_configs": { + "type": "array", + "nullable": true, + "items": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "protocol": { + "type": "string" + } + }, + "required": [ + "host" + ] + } + }, + "is_production": { + "type": "boolean", + "title": "Production", + "description": "Treat this target as a production environment." + }, + "allow_cookies": { + "type": "boolean", + "nullable": true, + "description": "Set true to forward the HTTP cookie header sent by clients to your origin and ensure the Set-Cookie header sent by your app is respected and not stripped." + }, + "enable_source_maps": { + "type": "boolean", + "nullable": true, + "description": "Set true to enable source map support. This will set the NODE_OPTIONS environment variable to \"--enable-source-maps\" in your MRT environment." + }, + "log_level": { + "nullable": true, + "description": "The minimum log level emitted for this target.\n\n* `TRACE`\n* `DEBUG`\n* `INFO`\n* `WARN`\n* `ERROR`\n* `FATAL`", + "oneOf": [ + { + "$ref": "#/components/schemas/LogLevelEnum" + }, + { + "$ref": "#/components/schemas/NullEnum" + } + ] + } + } + }, + "PatchedEmailNotification": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "targets": { + "type": "array", + "items": { + "type": "string", + "description": "User-friendly identifier for this target." + } + }, + "recipients": { + "type": "array", + "items": { + "type": "string", + "format": "email", + "maxLength": 254 + } + }, + "deployment_start": { + "type": "boolean", + "description": "Trigger this notification when a deployment starts for a target" + }, + "deployment_success": { + "type": "boolean", + "description": "Trigger this notification when a deployment succeeds for a target" + }, + "deployment_failed": { + "type": "boolean", + "description": "Trigger this notification when a deployment fails for a target" + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + }, + "updated_by": { + "type": "string", + "format": "email", + "title": "Email address", + "readOnly": true + } + } + }, + "PatchedEmailNotificationTyped": { + "allOf": [ + { + "type": "object", + "properties": { + "resourcetype": { + "type": "string" + } + } + }, + { + "$ref": "#/components/schemas/PatchedEmailNotification" + } + ] + }, + "PatchedPolymorphicNotification": { + "oneOf": [ + { + "$ref": "#/components/schemas/PatchedEmailNotificationTyped" + } + ], + "discriminator": { + "propertyName": "resourcetype", + "mapping": { + "EmailNotification": "#/components/schemas/PatchedEmailNotificationTyped" + } + } + }, + "PatchedUserEmailPreferences": { + "type": "object", + "properties": { + "node_deprecation_notifications": { + "type": "boolean", + "description": "The user's email notification preferences for Node.js runtime's deprecation and retirement." + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + } + } + }, + "PolymorphicNotification": { + "oneOf": [ + { + "$ref": "#/components/schemas/EmailNotificationTyped" + } + ], + "discriminator": { + "propertyName": "resourcetype", + "mapping": { + "EmailNotification": "#/components/schemas/EmailNotificationTyped" + } + } + }, + "ProjectTypeEnum": { + "enum": [ + "MOBIFY_STUDIO", + "MOBIFYJS_CLIENT", + "MOBIFY_ADAPTIVEJS", + "MOBIFY_TAG_BASED_PWA", + "SSR" + ], + "type": "string", + "description": "* `MOBIFY_STUDIO` - MOBIFY_STUDIO\n* `MOBIFYJS_CLIENT` - MOBIFYJS_CLIENT\n* `MOBIFY_ADAPTIVEJS` - MOBIFY_ADAPTIVEJS\n* `MOBIFY_TAG_BASED_PWA` - MOBIFY_TAG_BASED_PWA\n* `SSR` - SSR" + }, + "PublishingStatusEnum": { + "enum": [ + 0, + 1, + 2 + ], + "type": "integer", + "description": "* `0` - Pending\n* `1` - Completed\n* `2` - Failed" + }, + "ResourceLimit": { + "type": "object", + "properties": { + "limit": { + "type": "integer" + }, + "used": { + "type": "integer" + } + }, + "required": [ + "limit", + "used" + ] + }, + "SsrRegionEnum": { + "enum": [ + "us-east-1", + "us-east-2", + "us-west-1", + "us-west-2", + "ap-south-1", + "ap-south-2", + "ap-northeast-2", + "ap-southeast-1", + "ap-southeast-2", + "ap-southeast-3", + "ap-northeast-1", + "ap-northeast-3", + "ca-central-1", + "eu-central-1", + "eu-central-2", + "eu-west-1", + "eu-west-2", + "eu-west-3", + "eu-north-1", + "eu-south-1", + "il-central-1", + "me-central-1", + "sa-east-1" + ], + "type": "string", + "description": "* `us-east-1` - US East (N. Virginia)\n* `us-east-2` - US East (Ohio)\n* `us-west-1` - US West (N. California)\n* `us-west-2` - US West (Oregon)\n* `ap-south-1` - Asia Pacific (Mumbai)\n* `ap-south-2` - Asia Pacific (Hyderabad)\n* `ap-northeast-2` - Asia Pacific (Seoul)\n* `ap-southeast-1` - Asia Pacific (Singapore)\n* `ap-southeast-2` - Asia Pacific (Sydney)\n* `ap-southeast-3` - Asia Pacific (Jakarta)\n* `ap-northeast-1` - Asia Pacific (Tokyo)\n* `ap-northeast-3` - Asia Pacific (Osaka)\n* `ca-central-1` - Canada (Central)\n* `eu-central-1` - EU (Frankfurt)\n* `eu-central-2` - EU (Zurich)\n* `eu-west-1` - EU (Ireland)\n* `eu-west-2` - EU (London)\n* `eu-west-3` - EU (Paris)\n* `eu-north-1` - EU (Stockholm)\n* `eu-south-1` - EU (Milan)\n* `il-central-1` - Israel (Tel Aviv)\n* `me-central-1` - Middle East (UAE)\n* `sa-east-1` - South America (Sao Paulo)" + }, + "StateEnum": { + "enum": [ + "CREATE_IN_PROGRESS", + "PUBLISH_IN_PROGRESS", + "ACTIVE", + "CREATE_FAILED", + "PUBLISH_FAILED" + ], + "type": "string", + "description": "* `CREATE_IN_PROGRESS` - Create in Progress\n* `PUBLISH_IN_PROGRESS` - Publish in Progress\n* `ACTIVE` - Active\n* `CREATE_FAILED` - Create Failed\n* `PUBLISH_FAILED` - Publish Failed" + }, + "Status1d2Enum": { + "enum": [ + 0, + 1, + 2 + ], + "type": "integer", + "description": "* `0` - ok\n* `1` - broken\n* `2` - preparing" + }, + "UserEmailPreferences": { + "type": "object", + "properties": { + "node_deprecation_notifications": { + "type": "boolean", + "description": "The user's email notification preferences for Node.js runtime's deprecation and retirement." + }, + "created_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was created." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "description": "Timestamp in the extended ISO 8601 format for when the object was last updated." + } + } + } + }, + "securitySchemes": { + "Basic": { + "type": "http", + "description": "A basic authentication scheme for Managed Runtime API endpoints. To make an API request, concatenate your email address and API key separated by a colon (`:`). Base64 encode the concatenated string and include it in the HTTP request Authorization header.

Example:

`Authorization: Basic $B64_ENCODED_VALUE`", + "scheme": "basic" + }, + "BearerToken": { + "type": "http", + "description": "A bearer token authentication scheme for Managed Runtime API endpoints. To make an API request, include your API key in the HTTP request Authorization header.

Example:

`Authorization: Bearer $API_KEY`", + "scheme": "bearer", + "bearerFormat": "Bearer .*" + } + } + }, + "servers": [ + { + "url": "https://cloud.mobify.com" + } + ] +} diff --git a/packages/b2c-tooling/src/auth/api-key.ts b/packages/b2c-tooling/src/auth/api-key.ts index f39a24f9..98ac6525 100644 --- a/packages/b2c-tooling/src/auth/api-key.ts +++ b/packages/b2c-tooling/src/auth/api-key.ts @@ -1,12 +1,35 @@ import type {AuthStrategy} from './types.js'; import {getLogger} from '../logging/logger.js'; +/** + * API Key authentication strategy. + * + * Supports two modes: + * - Bearer token: When headerName is 'Authorization', formats as 'Bearer ' + * - Direct key: For other headers (e.g., 'x-api-key'), sets the key directly + * + * @example + * // For MRT API (Bearer token) + * const auth = new ApiKeyStrategy(apiKey, 'Authorization'); + * // Sets: Authorization: Bearer + * + * @example + * // For custom API key header + * const auth = new ApiKeyStrategy(apiKey, 'x-api-key'); + * // Sets: x-api-key: + */ export class ApiKeyStrategy implements AuthStrategy { - constructor( - private key: string, - private headerName = 'x-api-key', - ) { + private readonly headerValue: string; + private readonly headerName: string; + + constructor(key: string, headerName = 'x-api-key') { const logger = getLogger(); + this.headerName = headerName; + + // For Authorization header, use Bearer prefix (standard for MRT API) + // For other headers (like x-api-key), use the key directly + this.headerValue = headerName === 'Authorization' ? `Bearer ${key}` : key; + // Show partial key for identification (first 8 chars) const keyPreview = key.length > 8 ? `${key.slice(0, 8)}...` : key; logger.debug({headerName}, `[Auth] Using API Key authentication (${headerName}): ${keyPreview}`); @@ -14,7 +37,14 @@ export class ApiKeyStrategy implements AuthStrategy { async fetch(url: string, init: RequestInit = {}): Promise { const headers = new Headers(init.headers); - headers.set(this.headerName, this.key); + headers.set(this.headerName, this.headerValue); return fetch(url, {...init, headers}); } + + /** + * Returns the authorization header value for use with openapi-fetch middleware. + */ + async getAuthorizationHeader(): Promise { + return this.headerValue; + } } diff --git a/packages/b2c-tooling/src/cli/config.ts b/packages/b2c-tooling/src/cli/config.ts index 88b1befd..411f2c7b 100644 --- a/packages/b2c-tooling/src/cli/config.ts +++ b/packages/b2c-tooling/src/cli/config.ts @@ -1,7 +1,9 @@ import * as fs from 'node:fs'; +import * as os from 'node:os'; import * as path from 'node:path'; import type {AuthMethod} from '../auth/types.js'; import {ALL_AUTH_METHODS} from '../auth/types.js'; +import {getLogger} from '../logging/logger.js'; // Re-export for convenience export type {AuthMethod}; @@ -62,17 +64,22 @@ export interface LoadConfigOptions { * Finds dw.json by walking up from current directory. */ export function findDwJson(startDir: string = process.cwd()): string | null { + const logger = getLogger(); let dir = startDir; const root = path.parse(dir).root; + logger.trace({startDir}, '[Config] Searching for dw.json'); + while (dir !== root) { const dwJsonPath = path.join(dir, 'dw.json'); if (fs.existsSync(dwJsonPath)) { + logger.trace({path: dwJsonPath}, '[Config] Found dw.json'); return dwJsonPath; } dir = path.dirname(dir); } + logger.trace('[Config] No dw.json found'); return null; } @@ -100,8 +107,11 @@ function mapDwJsonToConfig(json: DwJsonConfig): ResolvedConfig { * Supports multi-config format with 'configs' array. */ function loadDwJson(instanceName?: string, configPath?: string): ResolvedConfig { + const logger = getLogger(); const dwJsonPath = configPath || findDwJson(); + if (!dwJsonPath || !fs.existsSync(dwJsonPath)) { + logger.trace('[Config] No dw.json to load'); return {}; } @@ -110,6 +120,7 @@ function loadDwJson(instanceName?: string, configPath?: string): ResolvedConfig const json = JSON.parse(content) as DwJsonMultiConfig; let selectedConfig: DwJsonConfig = json; + let selectedName = json.name || 'root'; // Handle multi-config format if (Array.isArray(json.configs)) { @@ -118,20 +129,23 @@ function loadDwJson(instanceName?: string, configPath?: string): ResolvedConfig const found = json.name === instanceName ? json : json.configs.find((c) => c.name === instanceName); if (found) { selectedConfig = found; + selectedName = found.name || instanceName; } } else if (json.active === false) { // Root config is inactive, find active one in configs const activeConfig = json.configs.find((c) => c.active === true); if (activeConfig) { selectedConfig = activeConfig; + selectedName = activeConfig.name || 'active'; } } // Otherwise use root config } + logger.trace({path: dwJsonPath, instance: selectedName}, '[Config] Loaded dw.json'); return mapDwJsonToConfig(selectedConfig); - } catch { - // Silently ignore parse errors + } catch (error) { + logger.trace({path: dwJsonPath, error}, '[Config] Failed to parse dw.json'); return {}; } } @@ -174,3 +188,60 @@ export function loadConfig(flags: Partial = {}, options: LoadCon const dwJsonConfig = loadDwJson(options.instance, options.configPath); return mergeConfigs(flags, dwJsonConfig, options); } + +/** + * Mobify config file structure (~/.mobify) + */ +interface MobifyConfig { + username?: string; + api_key?: string; +} + +/** + * Result from loading mobify config + */ +export interface MobifyConfigResult { + apiKey?: string; + username?: string; +} + +/** + * Loads MRT API key from ~/.mobify config file. + * + * The mobify config file is a JSON file located at ~/.mobify containing: + * ```json + * { + * "username": "user@example.com", + * "api_key": "your-api-key" + * } + * ``` + * + * @returns The API key and username if found, undefined otherwise + */ +export function loadMobifyConfig(): MobifyConfigResult { + const logger = getLogger(); + const mobifyPath = path.join(os.homedir(), '.mobify'); + + logger.trace({path: mobifyPath}, '[Config] Checking for ~/.mobify'); + + if (!fs.existsSync(mobifyPath)) { + logger.trace('[Config] No ~/.mobify found'); + return {}; + } + + try { + const content = fs.readFileSync(mobifyPath, 'utf8'); + const config = JSON.parse(content) as MobifyConfig; + + const hasApiKey = Boolean(config.api_key); + logger.trace({path: mobifyPath, hasApiKey, username: config.username}, '[Config] Loaded ~/.mobify'); + + return { + apiKey: config.api_key, + username: config.username, + }; + } catch (error) { + logger.trace({path: mobifyPath, error}, '[Config] Failed to parse ~/.mobify'); + return {}; + } +} diff --git a/packages/b2c-tooling/src/cli/index.ts b/packages/b2c-tooling/src/cli/index.ts index 1adfcdf1..f8fc61b8 100644 --- a/packages/b2c-tooling/src/cli/index.ts +++ b/packages/b2c-tooling/src/cli/index.ts @@ -11,3 +11,7 @@ export {OdsCommand} from './ods-command.js'; // Config utilities export {loadConfig, findDwJson} from './config.js'; export type {ResolvedConfig, LoadConfigOptions} from './config.js'; + +// Table rendering utilities +export {TableRenderer, createTable} from './table.js'; +export type {ColumnDef, TableRenderOptions} from './table.js'; diff --git a/packages/b2c-tooling/src/cli/mrt-command.ts b/packages/b2c-tooling/src/cli/mrt-command.ts index 53b25296..2a7e6f55 100644 --- a/packages/b2c-tooling/src/cli/mrt-command.ts +++ b/packages/b2c-tooling/src/cli/mrt-command.ts @@ -1,6 +1,6 @@ import {Command, Flags} from '@oclif/core'; import {BaseCommand} from './base-command.js'; -import {loadConfig} from './config.js'; +import {loadConfig, loadMobifyConfig} from './config.js'; import type {ResolvedConfig, LoadConfigOptions} from './config.js'; import type {AuthStrategy} from '../auth/types.js'; import {ApiKeyStrategy} from '../auth/api-key.js'; @@ -11,6 +11,11 @@ import {t} from '../i18n/index.js'; /** * Base command for Managed Runtime (MRT) operations. * Uses API key authentication. + * + * API key resolution order: + * 1. --api-key flag + * 2. SFCC_MRT_API_KEY environment variable + * 3. ~/.mobify config file (api_key field) */ export abstract class MrtCommand extends BaseCommand { static baseFlags = { @@ -28,8 +33,12 @@ export abstract class MrtCommand extends BaseCommand = { - mrtApiKey: this.flags['api-key'], + // Flag/env takes precedence, then ~/.mobify + mrtApiKey: this.flags['api-key'] || mobifyConfig.apiKey, }; return loadConfig(flagConfig, options); @@ -45,7 +54,12 @@ export abstract class MrtCommand extends BaseCommand extends BaseCommand> = { + * name: { header: 'Name', get: (u) => u.name }, + * email: { header: 'Email', get: (u) => u.email }, + * role: { header: 'Role', get: (u) => u.role }, + * }; + * + * const table = new TableRenderer(columns); + * table.render(users, ['name', 'email', 'role']); + * ``` + */ +import {ux} from '@oclif/core'; +import cliui from 'cliui'; + +/** + * Column definition for table output. + * + * @typeParam T - The type of data items being rendered + */ +export interface ColumnDef { + /** Column header label */ + header: string; + /** Function to extract display value from a data item */ + get: (item: T) => string; + /** Minimum width in characters (optional) */ + minWidth?: number; + /** Whether this column is only shown in extended mode (optional) */ + extended?: boolean; +} + +/** + * Options for table rendering. + */ +export interface TableRenderOptions { + /** Terminal width override (defaults to process.stdout.columns or 120) */ + termWidth?: number; + /** Column padding (defaults to 2) */ + padding?: number; +} + +/** + * A reusable table renderer for CLI output. + * + * Handles dynamic column width calculation based on content and provides + * consistent table formatting across all CLI commands. + * + * @typeParam T - The type of data items being rendered + * + * @example + * ```typescript + * // Define columns for your data type + * const columns: Record> = { + * id: { header: 'ID', get: (d) => d.id }, + * name: { header: 'Name', get: (d) => d.name }, + * status: { header: 'Status', get: (d) => d.status }, + * }; + * + * // Create renderer and render data + * const table = new TableRenderer(columns); + * table.render(items, ['id', 'name', 'status']); + * + * // Or with custom options + * table.render(items, ['id', 'name'], { padding: 3 }); + * ``` + */ +export class TableRenderer { + /** + * Creates a new TableRenderer. + * + * @param columns - Column definitions keyed by column identifier + */ + constructor(private columns: Record>) {} + + /** + * Renders data as a formatted table to stdout. + * + * @param data - Array of data items to render + * @param columnKeys - Array of column keys to display (in order) + * @param options - Optional rendering options + */ + render(data: T[], columnKeys: string[], options: TableRenderOptions = {}): void { + const termWidth = options.termWidth ?? process.stdout.columns ?? 120; + const padding = options.padding ?? 2; + + const ui = cliui({width: termWidth}); + const widths = this.calculateColumnWidths(data, columnKeys, padding); + + // Header row + const headerCols = columnKeys.map((key) => ({ + text: this.columns[key].header, + width: widths.get(key), + padding: [0, 1, 0, 0] as [number, number, number, number], + })); + ui.div(...headerCols); + + // Separator + const totalWidth = [...widths.values()].reduce((sum, w) => sum + w, 0); + ui.div({text: '─'.repeat(Math.min(totalWidth, termWidth)), padding: [0, 0, 0, 0]}); + + // Data rows + for (const item of data) { + const rowCols = columnKeys.map((key) => ({ + text: this.columns[key].get(item), + width: widths.get(key), + padding: [0, 1, 0, 0] as [number, number, number, number], + })); + ui.div(...rowCols); + } + + ux.stdout(ui.toString()); + } + + /** + * Gets the list of available column keys. + * + * @returns Array of all column keys + */ + getColumnKeys(): string[] { + return Object.keys(this.columns); + } + + /** + * Gets column keys excluding extended columns. + * + * @returns Array of non-extended column keys + */ + getDefaultColumnKeys(): string[] { + return Object.entries(this.columns) + .filter(([, col]) => !col.extended) + .map(([key]) => key); + } + + /** + * Validates and filters column keys. + * + * @param requested - Requested column keys + * @returns Valid column keys that exist in the columns definition + */ + validateColumnKeys(requested: string[]): string[] { + return requested.filter((key) => key in this.columns); + } + + /** + * Calculates dynamic column widths based on content. + * + * @param data - Data items to measure + * @param columnKeys - Columns to calculate widths for + * @param padding - Padding to add to each column + * @returns Map of column key to calculated width + */ + private calculateColumnWidths(data: T[], columnKeys: string[], padding: number): Map { + const widths = new Map(); + + for (const key of columnKeys) { + const col = this.columns[key]; + let maxWidth = col.header.length; + + for (const item of data) { + const value = col.get(item); + maxWidth = Math.max(maxWidth, value.length); + } + + const minWidth = col.minWidth ?? 0; + widths.set(key, Math.max(maxWidth, minWidth) + padding); + } + + return widths; + } +} + +/** + * Creates a TableRenderer instance. + * + * Convenience function for creating a table renderer. + * + * @typeParam T - The type of data items being rendered + * @param columns - Column definitions + * @returns A new TableRenderer instance + * + * @example + * ```typescript + * const table = createTable({ + * name: { header: 'Name', get: (u) => u.name }, + * email: { header: 'Email', get: (u) => u.email }, + * }); + * table.render(users, ['name', 'email']); + * ``` + */ +export function createTable(columns: Record>): TableRenderer { + return new TableRenderer(columns); +} diff --git a/packages/b2c-tooling/src/clients/index.ts b/packages/b2c-tooling/src/clients/index.ts index ec14d9fe..6c82cfb2 100644 --- a/packages/b2c-tooling/src/clients/index.ts +++ b/packages/b2c-tooling/src/clients/index.ts @@ -110,7 +110,7 @@ export {WebDavClient} from './webdav.js'; export type {PropfindEntry} from './webdav.js'; export {createAuthMiddleware, createLoggingMiddleware, createExtraParamsMiddleware} from './middleware.js'; -export type {ExtraParamsConfig} from './middleware.js'; +export type {ExtraParamsConfig, LoggingMiddlewareConfig} from './middleware.js'; export {createOcapiClient} from './ocapi.js'; export type { @@ -140,3 +140,14 @@ export type { paths as OdsPaths, components as OdsComponents, } from './ods.js'; + +export {createMrtClient, DEFAULT_MRT_ORIGIN} from './mrt.js'; +export type { + MrtClient, + MrtClientConfig, + MrtError, + MrtResponse, + BuildPushResponse, + paths as MrtPaths, + components as MrtComponents, +} from './mrt.js'; diff --git a/packages/b2c-tooling/src/clients/middleware.ts b/packages/b2c-tooling/src/clients/middleware.ts index 718c4ab5..8758c6f7 100644 --- a/packages/b2c-tooling/src/clients/middleware.ts +++ b/packages/b2c-tooling/src/clients/middleware.ts @@ -52,15 +52,65 @@ export function createAuthMiddleware(auth: AuthStrategy): Middleware { }; } +/** + * Configuration for logging middleware. + */ +export interface LoggingMiddlewareConfig { + /** + * Prefix for log messages (e.g., 'OCAPI', 'SLAS', 'MRT'). + */ + prefix?: string; + + /** + * Body keys to mask in logs (replaced with '...' placeholder). + * Useful for large payloads like base64-encoded file data. + * @example ['data', 'password', 'secret'] + */ + maskBodyKeys?: string[]; +} + +/** + * Masks specified keys in an object for logging. + * Only masks top-level keys, replaces values with '...' placeholder. + */ +function maskBody(body: unknown, keysToMask?: string[]): unknown { + if (!keysToMask || keysToMask.length === 0 || typeof body !== 'object' || body === null) { + return body; + } + + const masked = {...(body as Record)}; + for (const key of keysToMask) { + if (key in masked) { + masked[key] = '...'; + } + } + return masked; +} + /** * Creates logging middleware for openapi-fetch clients. * * Logs request/response details at debug and trace levels. * - * @param prefix - Optional prefix for log messages (e.g., 'OCAPI', 'SLAS') + * @param config - Logging configuration or prefix string for backwards compatibility * @returns Middleware that logs requests and responses + * + * @example + * // Simple usage with just a prefix + * client.use(createLoggingMiddleware('OCAPI')); + * + * @example + * // With body masking for large payloads + * client.use(createLoggingMiddleware({ + * prefix: 'MRT', + * maskBodyKeys: ['data'] // Masks base64-encoded bundle data + * })); */ -export function createLoggingMiddleware(prefix?: string): Middleware { +export function createLoggingMiddleware(config?: string | LoggingMiddlewareConfig): Middleware { + // Support both string (prefix) and config object for backwards compatibility + const {prefix, maskBodyKeys} = + typeof config === 'string' ? {prefix: config, maskBodyKeys: undefined} : (config ?? {}); + const reqTag = prefix ? `[${prefix} REQ]` : ''; const respTag = prefix ? `[${prefix} RESP]` : ''; @@ -82,7 +132,13 @@ export function createLoggingMiddleware(prefix?: string): Middleware { body = text; } } - logger.trace({headers: headersToObject(request.headers), body}, `${reqTag} ${request.method} ${url} body`); + + // Mask sensitive/large body keys before logging + const maskedBody = maskBody(body, maskBodyKeys); + logger.trace( + {headers: headersToObject(request.headers), body: maskedBody}, + `${reqTag} ${request.method} ${url} body`, + ); (request as Request & {_startTime?: number})._startTime = Date.now(); @@ -108,8 +164,10 @@ export function createLoggingMiddleware(prefix?: string): Middleware { responseBody = await clonedResponse.text(); } + // Mask sensitive/large body keys before logging + const maskedResponseBody = maskBody(responseBody, maskBodyKeys); logger.trace( - {headers: headersToObject(response.headers), body: responseBody}, + {headers: headersToObject(response.headers), body: maskedResponseBody}, `${respTag} ${request.method} ${url} body`, ); diff --git a/packages/b2c-tooling/src/clients/mrt.generated.ts b/packages/b2c-tooling/src/clients/mrt.generated.ts new file mode 100644 index 00000000..a3f088b8 --- /dev/null +++ b/packages/b2c-tooling/src/clients/mrt.generated.ts @@ -0,0 +1,2775 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + "/api/organizations/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List organizations. */ + get: operations["organizations_list"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List projects. */ + get: operations["projects_list"]; + put?: never; + /** @description Create a project. */ + post: operations["projects_create"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Read data about a project. */ + get: operations["projects_retrieve"]; + put?: never; + post?: never; + /** @description Delete a project. */ + delete: operations["projects_destroy"]; + options?: never; + head?: never; + /** @description Update a project. */ + patch: operations["projects_partial_update"]; + trace?: never; + }; + "/api/projects/{project_slug}/builds/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Upload a bundle. */ + post: operations["projects_builds_create"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/builds/{target_slug}/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Upload a bundle and deploy it to an environment asynchronously. */ + post: operations["projects_builds_create_and_deploy"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/bundles/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List bundles of a project */ + get: operations["projects_bundles_list"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/bundles/{bundle_id}/download/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Get a presigned URL (active for one hour) to download a bundle archive. */ + get: operations["projects_bundles_download_retrieve"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/members/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List a project's members. */ + get: operations["projects_members_list"]; + put?: never; + /** @description Create a new project member. */ + post: operations["projects_members_create"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/members/{email}/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Read data about a project member's permissions. */ + get: operations["projects_members_retrieve"]; + put?: never; + post?: never; + /** @description Delete a project member. */ + delete: operations["projects_members_destroy"]; + options?: never; + head?: never; + /** @description Update a project member's permissions. */ + patch: operations["projects_members_partial_update"]; + trace?: never; + }; + "/api/projects/{project_slug}/notifications/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List notifications for a project */ + get: operations["projects_notifications_list"]; + put?: never; + /** @description Create notification for a Project */ + post: operations["projects_notifications_create"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/notifications/{id}/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Read data about a notification. */ + get: operations["projects_notifications_retrieve"]; + put?: never; + post?: never; + /** @description Delete a notification. */ + delete: operations["projects_notifications_destroy"]; + options?: never; + head?: never; + /** @description Update a project's notification. */ + patch: operations["projects_notifications_partial_update"]; + trace?: never; + }; + "/api/projects/{project_slug}/target/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List a project's targets. */ + get: operations["projects_target_list"]; + put?: never; + /** @description Create a new target. */ + post: operations["projects_target_create"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/target/{target_slug}/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Read data about a target. */ + get: operations["projects_target_retrieve"]; + put?: never; + post?: never; + /** @description Delete a target. */ + delete: operations["projects_target_destroy"]; + options?: never; + head?: never; + /** @description Update a target. Important: This endpoint automatically re-deploys the current bundle if any of the SSR-related properties are changed. */ + patch: operations["projects_target_partial_update"]; + trace?: never; + }; + "/api/projects/{project_slug}/target/{target_slug}/access-control-header/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List a target's access control headers. */ + get: operations["projects_target_access_control_header_list"]; + put?: never; + /** @description Create an access control header to restrict access to an environment so that only trusted traffic coming from your content delivery network (CDN) or development team is allowed. Requests to this environment must contain the header `x-sfdc-access-control` with the value provided or they will be rejected. Accepts an object with a value for a single access control header. See [Access Control Headers](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html?q=access%20control%20header#access-control-headers). */ + post: operations["projects_target_access_control_header_create"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/target/{target_slug}/access-control-header/{id}/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Read data about an access control header by its id. */ + get: operations["projects_target_access_control_header_retrieve"]; + put?: never; + post?: never; + /** @description Delete an access control header by its id. */ + delete: operations["projects_target_access_control_header_destroy"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/target/{target_slug}/deploy/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Get the deployment history of a target. */ + get: operations["projects_target_deploy_list"]; + put?: never; + /** @description Deploys a bundle to a target. Returns the status of the deploy. Deployment details are not immediately available in the response as this endpoint is asynchronous. Request the target for progress updates. */ + post: operations["projects_target_deploy_create"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/target/{target_slug}/env-var/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List a target's environment variables. */ + get: operations["projects_target_env_var_list"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + /** @description Create, update, or delete environment variables. Accepts an object with values for single or multiple environment variables. If the variable does not exist, it is created. If the variable exists, it is updated. And if the variable exists and the value is null, it is deleted. */ + patch: operations["projects_target_env_var_partial_update"]; + trace?: never; + }; + "/api/projects/{project_slug}/target/{target_slug}/invalidation/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Invalidate a target's cached objects in the CDN. Cache invalidations are asynchronous and usually complete within two minutes. */ + post: operations["projects_target_invalidation_create"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/target/{target_slug}/redirect/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List a target's redirects. See [Redirects](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#redirects). */ + get: operations["projects_target_redirect_list"]; + put?: never; + /** @description Create one or more redirects. This endpoint accepts either an object with values for a single redirect, or an array of objects for bulk creation. For example, consider a seasonal campaign page for spring. When the spring campaign ends and is replaced with a summer campaign, you can redirect from the spring URL to the summer URL. We recommend that you always create redirects in your staging target (environment) and then [clone](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-admin?meta=projects_target_redirect_clone_create) them to your production target. This allows you to test the redirects and verify that they work as expected. Changes may take up to 20 minutes to take effect on your site. See [Redirects](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#redirects). */ + post: operations["projects_target_redirect_create"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{project_slug}/target/{target_slug}/redirect/{from_path}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Read data about a redirect by `from_path`. See [Redirects](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#redirects). */ + get: operations["projects_target_redirect_retrieve"]; + put?: never; + post?: never; + /** @description Delete a redirect by `from_path`. For example, you can delete a redirect that's no longer needed because a seasonal campaign is over, you removed a page, or you want to streamline your redirect structure and improve search engine ranking. We recommend that you always delete redirects in your staging target (environment), and then [clone](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-admin?meta=projects_target_redirect_clone_create) the changes to your production target. Changes may take up to 20 minutes to take effect on your site. When you delete a redirect, you no longer see it in Runtime Admin. See [Redirects](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#redirects). */ + delete: operations["projects_target_redirect_destroy"]; + options?: never; + head?: never; + /** @description Update a redirect by `from_path`. For example, you can change a redirect if your content moved or you rebranded with new pages. We recommend that you always change redirects in your staging target (environment), and then [clone](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-admin?meta=projects_target_redirect_clone_create) the changes to your production target. Changes may take up to 20 minutes to take effect on your site. See [Redirects](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#redirects). */ + patch: operations["projects_target_redirect_partial_update"]; + trace?: never; + }; + "/api/projects/{project_slug}/target/{to_target_slug}/redirect/clone/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Clone redirects from one target to another. Important: when you clone redirects, you're replacing all the redirects in one target with all the redirects in the other. See [Redirects](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#redirects). */ + post: operations["projects_target_redirect_clone_create"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/users/me/api_key/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Generate or reset the API key. */ + post: operations["users_me_api_key_create"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/users/me/email-preferences/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Get email notification preferences for the authenticated user. */ + get: operations["users_me_email_preferences_retrieve"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + /** @description Update email notification preferences for the authenticated user. */ + patch: operations["users_me_email_preferences_partial_update"]; + trace?: never; + }; + "/api/users/me/profile/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Get the profile information for the authenticated user. */ + get: operations["users_me_profile_retrieve"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; +} +export type webhooks = Record; +export interface components { + schemas: { + APIAccessControlHeaderV2Create: { + /** + * Format: uuid + * @description Id for this Access Control Header. + */ + readonly id?: string; + /** @description Value to be encrypted. A header value is made up of your chosen set of characters. For the constraints that apply to the value, see [Access Control Headers](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html?q=access%20control%20header#access-control-headers). */ + value: string; + /** + * Email address + * Format: email + */ + readonly user_email?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + readonly publishing_status?: components["schemas"]["PublishingStatusEnum"]; + readonly publishing_status_description?: string; + }; + APIOrganization: { + /** Format: uuid */ + readonly uuid?: string; + name: string; + slug: string; + readonly deletion_status?: components["schemas"]["DeletionStatusEnum"]; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + readonly permissions?: { + create_project?: boolean; + }; + readonly has_mobify_tag_project?: boolean; + readonly limits?: components["schemas"]["OrganizationLimits"]; + readonly auto_delete?: components["schemas"]["OrganizationAutoDelete"]; + }; + APIProjectMember: { + /** + * Email address + * Format: email + */ + user: string; + role: { + name?: string; + /** @enum {integer} */ + value?: 0 | 1 | 2 | 3; + }; + }; + APIProjectV2Create: { + /** @description User-friendly name for this project */ + name: string; + /** Format: uri */ + url?: string; + slug?: string; + /** @description User-friendly identifier for this instance. */ + organization: string; + readonly deletion_status?: components["schemas"]["DeletionStatusEnum"]; + readonly project_type?: components["schemas"]["ProjectTypeEnum"]; + readonly permissions?: { + browse?: boolean; + deploy?: boolean; + delete_bundle?: boolean; + delete_project?: boolean; + edit_redirect?: boolean; + edit_roles?: boolean; + edit_settings?: boolean; + validate_tag?: boolean; + edit_environment?: boolean; + create_environment?: boolean; + delete_environment?: boolean; + create_notification?: boolean; + list_notifications?: boolean; + retrieve_notification?: boolean; + edit_notification?: boolean; + delete_notification?: boolean; + create_jwt?: boolean; + upload_bundle?: boolean; + edit_environment_variable?: boolean; + edit_access_control_header?: boolean; + }; + /** + * SSR AWS Region + * @description The default AWS region for newly created targets + * + * * `us-east-1` - US East (N. Virginia) + * * `us-east-2` - US East (Ohio) + * * `us-west-1` - US West (N. California) + * * `us-west-2` - US West (Oregon) + * * `ap-south-1` - Asia Pacific (Mumbai) + * * `ap-south-2` - Asia Pacific (Hyderabad) + * * `ap-northeast-2` - Asia Pacific (Seoul) + * * `ap-southeast-1` - Asia Pacific (Singapore) + * * `ap-southeast-2` - Asia Pacific (Sydney) + * * `ap-southeast-3` - Asia Pacific (Jakarta) + * * `ap-northeast-1` - Asia Pacific (Tokyo) + * * `ap-northeast-3` - Asia Pacific (Osaka) + * * `ca-central-1` - Canada (Central) + * * `eu-central-1` - EU (Frankfurt) + * * `eu-central-2` - EU (Zurich) + * * `eu-west-1` - EU (Ireland) + * * `eu-west-2` - EU (London) + * * `eu-west-3` - EU (Paris) + * * `eu-north-1` - EU (Stockholm) + * * `eu-south-1` - EU (Milan) + * * `il-central-1` - Israel (Tel Aviv) + * * `me-central-1` - Middle East (UAE) + * * `sa-east-1` - South America (Sao Paulo) + */ + ssr_region?: components["schemas"]["SsrRegionEnum"]; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + }; + APIProjectV2Update: { + /** @description User-friendly name for this project */ + name: string; + /** Format: uri */ + url?: string; + readonly slug?: string; + /** @description User-friendly identifier for this instance. */ + organization?: string; + readonly deletion_status?: components["schemas"]["DeletionStatusEnum"]; + readonly project_type?: components["schemas"]["ProjectTypeEnum"]; + readonly permissions?: { + browse?: boolean; + deploy?: boolean; + delete_bundle?: boolean; + delete_project?: boolean; + edit_redirect?: boolean; + edit_roles?: boolean; + edit_settings?: boolean; + validate_tag?: boolean; + edit_environment?: boolean; + create_environment?: boolean; + delete_environment?: boolean; + create_notification?: boolean; + list_notifications?: boolean; + retrieve_notification?: boolean; + edit_notification?: boolean; + delete_notification?: boolean; + create_jwt?: boolean; + upload_bundle?: boolean; + edit_environment_variable?: boolean; + edit_access_control_header?: boolean; + }; + /** + * SSR AWS Region + * @description The default AWS region for newly created targets + * + * * `us-east-1` - US East (N. Virginia) + * * `us-east-2` - US East (Ohio) + * * `us-west-1` - US West (N. California) + * * `us-west-2` - US West (Oregon) + * * `ap-south-1` - Asia Pacific (Mumbai) + * * `ap-south-2` - Asia Pacific (Hyderabad) + * * `ap-northeast-2` - Asia Pacific (Seoul) + * * `ap-southeast-1` - Asia Pacific (Singapore) + * * `ap-southeast-2` - Asia Pacific (Sydney) + * * `ap-southeast-3` - Asia Pacific (Jakarta) + * * `ap-northeast-1` - Asia Pacific (Tokyo) + * * `ap-northeast-3` - Asia Pacific (Osaka) + * * `ca-central-1` - Canada (Central) + * * `eu-central-1` - EU (Frankfurt) + * * `eu-central-2` - EU (Zurich) + * * `eu-west-1` - EU (Ireland) + * * `eu-west-2` - EU (London) + * * `eu-west-3` - EU (Paris) + * * `eu-north-1` - EU (Stockholm) + * * `eu-south-1` - EU (Milan) + * * `il-central-1` - Israel (Tel Aviv) + * * `me-central-1` - Middle East (UAE) + * * `sa-east-1` - South America (Sao Paulo) + */ + ssr_region?: components["schemas"]["SsrRegionEnum"]; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + }; + APIRedirectV2Clone: { + from_target_slug: string; + }; + APIRedirectV2CreateUpdate: { + /** @description A relative URL. For example, the `from_path` value `/spring` redirects shoppers from the URL `www.example.com/spring`. An asterisk (`*`) at the end of the `from_path` indicates a wildcard. For example, a redirect from `/a/*` matches `/a/`, `/a/b`, and `/a/b/c`. */ + from_path: string; + /** @description A relative or absolute URL. For example, the `to_url` value `/summer` redirects shoppers to the URL `www.example.com/summer`. */ + to_url: string; + /** @description Some requests contain query string parameters to include in the redirected request. For example, the relative path `/spring-landing-page` can be appended with a query string for analytics tracking, such as `/spring-landing-page?gclid=123`. The `true` value includes query string parameters in the redirect. The `false` value excludes query string parameters from the redirect. The default value is `false`. */ + forward_querystring?: boolean | null; + /** @description The `true` value automatically includes any path that comes after the wildcard portion of the `from_path` in the `to_url`. For example: if `/a/*` matches `/a/b/c` in the `from_path` and the `to_url` is `/z/`, the redirect URL is `/z/b/c`. The `false` value excludes the wildcard portion. The default value is `false`. */ + forward_wildcard?: boolean | null; + /** + * @description The HTTP status code to be returned in the response. 301 (Moved Permanently) is the recommended and default value. 302 (Found or Moved Temporarily) is another allowable value. For more information about HTTP status codes, see this [status code explainer](https://moz.com/learn/seo/redirection). + * + * * `301` - Permanent 301 + * * `302` - Temporary 302 + */ + http_status_code?: components["schemas"]["HttpStatusCodeEnum"]; + /** @description The status of the redeployment that happens after you call this API. Allowable values: Pending, Completed, Failed. If the request failed, you can [redeploy the environment](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/pushing-and-deploying-bundles.html) specified in your request. */ + readonly publishing_status?: string; + /** + * Email address + * Format: email + * @description Email of the user who created the redirect. + */ + readonly user_email?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + /** + * Email address + * Format: email + * @description Email of the user who last updated the redirect. + */ + readonly updated_by?: string; + }; + /** @description This is the serializer for target create/list APIs. */ + APITargetV2Create: { + slug?: string; + /** @description User-friendly name for this target */ + name: string; + /** + * @description Target State + * + * * `CREATE_IN_PROGRESS` - Create in Progress + * * `PUBLISH_IN_PROGRESS` - Publish in Progress + * * `ACTIVE` - Active + * * `CREATE_FAILED` - Create Failed + * * `PUBLISH_FAILED` - Publish Failed + */ + readonly state?: components["schemas"]["StateEnum"]; + readonly deletion_status?: components["schemas"]["DeletionStatusEnum"]; + /** @description Hostname (literal or JavaScript regular expression between / characters) on which this target should be loaded by the V8 Tag */ + hostname?: string | null; + readonly current_deploy?: { + [key: string]: unknown; + }; + /** @description Full hostname to used by the environment eg. www.customer.com. */ + ssr_external_hostname?: string | null; + /** @description The domain to be used for a Universal PWA SSR deployment (e.g. customer.com) */ + ssr_external_domain?: string | null; + /** + * SSR AWS Region + * @description The AWS region to which a Universal PWA SSR should be deployed (e.g. us-east-1) + * + * * `us-east-1` - US East (N. Virginia) + * * `us-east-2` - US East (Ohio) + * * `us-west-1` - US West (N. California) + * * `us-west-2` - US West (Oregon) + * * `ap-south-1` - Asia Pacific (Mumbai) + * * `ap-south-2` - Asia Pacific (Hyderabad) + * * `ap-northeast-2` - Asia Pacific (Seoul) + * * `ap-southeast-1` - Asia Pacific (Singapore) + * * `ap-southeast-2` - Asia Pacific (Sydney) + * * `ap-southeast-3` - Asia Pacific (Jakarta) + * * `ap-northeast-1` - Asia Pacific (Tokyo) + * * `ap-northeast-3` - Asia Pacific (Osaka) + * * `ca-central-1` - Canada (Central) + * * `eu-central-1` - EU (Frankfurt) + * * `eu-central-2` - EU (Zurich) + * * `eu-west-1` - EU (Ireland) + * * `eu-west-2` - EU (London) + * * `eu-west-3` - EU (Paris) + * * `eu-north-1` - EU (Stockholm) + * * `eu-south-1` - EU (Milan) + * * `il-central-1` - Israel (Tel Aviv) + * * `me-central-1` - Middle East (UAE) + * * `sa-east-1` - South America (Sao Paulo) + */ + ssr_region?: components["schemas"]["SsrRegionEnum"] | components["schemas"]["BlankEnum"]; + /** @description Optional space-separated list of IP addresses (CIDR blocks) that can access this target. Leave blank to allow all IPs. */ + ssr_whitelisted_ips?: string | null; + ssr_proxy_configs?: { + host: string; + protocol?: string; + }[] | null; + /** + * Production + * @description Treat this target as a production environment. + */ + is_production?: boolean; + /** @description Set true to forward the HTTP cookie header sent by clients to your origin and ensure the Set-Cookie header sent by your app is respected and not stripped. */ + allow_cookies?: boolean | null; + /** @description Set true to enable source map support. This will set the NODE_OPTIONS environment variable to "--enable-source-maps" in your MRT environment. */ + enable_source_maps?: boolean | null; + /** + * @description The minimum log level emitted for this target.n + * * `TRACE` + * * `DEBUG` + * * `INFO` + * * `WARN` + * * `ERROR` + * * `FATAL` + */ + log_level?: (components["schemas"]["LogLevelEnum"] | components["schemas"]["NullEnum"]) | null; + }; + /** @description This is the serializer for cache invalidation API endpoint. */ + APITargetV2CreateInvalidation: { + /** @description Path pattern to invalidate on the CDN. This must start with a forward slash (`/`). */ + pattern: string; + /** + * @deprecated + * @description [Deprecated] Items to invalidate in the application cache. + * @default [] + */ + items: string[] | null; + /** + * @deprecated + * @description [Deprecated] Namespace of items to invalidate in the application cache. + */ + namespace?: string; + }; + /** @description This is the base Target serializer. */ + APITargetV2Update: { + readonly slug?: string; + /** @description User-friendly name for this target */ + name: string; + /** + * @description Target State + * + * * `CREATE_IN_PROGRESS` - Create in Progress + * * `PUBLISH_IN_PROGRESS` - Publish in Progress + * * `ACTIVE` - Active + * * `CREATE_FAILED` - Create Failed + * * `PUBLISH_FAILED` - Publish Failed + */ + readonly state?: components["schemas"]["StateEnum"]; + readonly deletion_status?: components["schemas"]["DeletionStatusEnum"]; + /** @description Hostname (literal or JavaScript regular expression between / characters) on which this target should be loaded by the V8 Tag */ + hostname?: string | null; + readonly current_deploy?: { + [key: string]: unknown; + }; + /** @description Full hostname to used by the environment eg. www.customer.com. */ + ssr_external_hostname?: string | null; + /** @description The domain to be used for a Universal PWA SSR deployment (e.g. customer.com) */ + ssr_external_domain?: string | null; + /** + * SSR AWS Region + * @description The AWS region to which a Universal PWA SSR should be deployed (e.g. us-east-1) + * + * * `us-east-1` - US East (N. Virginia) + * * `us-east-2` - US East (Ohio) + * * `us-west-1` - US West (N. California) + * * `us-west-2` - US West (Oregon) + * * `ap-south-1` - Asia Pacific (Mumbai) + * * `ap-south-2` - Asia Pacific (Hyderabad) + * * `ap-northeast-2` - Asia Pacific (Seoul) + * * `ap-southeast-1` - Asia Pacific (Singapore) + * * `ap-southeast-2` - Asia Pacific (Sydney) + * * `ap-southeast-3` - Asia Pacific (Jakarta) + * * `ap-northeast-1` - Asia Pacific (Tokyo) + * * `ap-northeast-3` - Asia Pacific (Osaka) + * * `ca-central-1` - Canada (Central) + * * `eu-central-1` - EU (Frankfurt) + * * `eu-central-2` - EU (Zurich) + * * `eu-west-1` - EU (Ireland) + * * `eu-west-2` - EU (London) + * * `eu-west-3` - EU (Paris) + * * `eu-north-1` - EU (Stockholm) + * * `eu-south-1` - EU (Milan) + * * `il-central-1` - Israel (Tel Aviv) + * * `me-central-1` - Middle East (UAE) + * * `sa-east-1` - South America (Sao Paulo) + */ + ssr_region?: components["schemas"]["SsrRegionEnum"] | components["schemas"]["BlankEnum"]; + /** @description Optional space-separated list of IP addresses (CIDR blocks) that can access this target. Leave blank to allow all IPs. */ + ssr_whitelisted_ips?: string | null; + ssr_proxy_configs?: { + host: string; + protocol?: string; + }[] | null; + /** + * Production + * @description Treat this target as a production environment. + */ + is_production?: boolean; + /** @description Set true to forward the HTTP cookie header sent by clients to your origin and ensure the Set-Cookie header sent by your app is respected and not stripped. */ + allow_cookies?: boolean | null; + /** @description Set true to enable source map support. This will set the NODE_OPTIONS environment variable to "--enable-source-maps" in your MRT environment. */ + enable_source_maps?: boolean | null; + /** + * @description The minimum log level emitted for this target.n + * * `TRACE` + * * `DEBUG` + * * `INFO` + * * `WARN` + * * `ERROR` + * * `FATAL` + */ + log_level?: (components["schemas"]["LogLevelEnum"] | components["schemas"]["NullEnum"]) | null; + }; + APIUserProfile: { + first_name?: string; + last_name?: string; + /** + * Email address + * Format: email + */ + readonly email?: string; + /** + * Staff status + * @description Designates whether the user can log into this admin site. + */ + readonly is_staff?: boolean; + /** Format: date-time */ + readonly date_joined?: string; + /** Format: uuid */ + readonly uuid?: string; + readonly highest_account_manager_role?: string; + }; + /** @enum {unknown} */ + BlankEnum: ""; + /** @description Serializer to validate a bundle upload payload. */ + Bundle: { + message: string; + data: string; + encoding: components["schemas"]["EncodingEnum"]; + ssr_only?: string[]; + ssr_shared?: string[]; + ssr_parameters?: { + [key: string]: unknown; + }; + bundle_metadata?: { + [key: string]: unknown; + }; + }; + BundleDownload: { + /** Format: uri */ + download_url: string; + }; + BundleList: { + /** @description A ID unique within a project. */ + id: number; + message: string; + status?: components["schemas"]["Status1d2Enum"]; + deletion_status?: components["schemas"]["DeletionStatusEnum"]; + /** + * Email address + * Format: email + */ + readonly user?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + }; + /** + * @description * `ACTIVE` - Active + * * `CLEANUP_REQUESTED` - Cleanup Requested + * * `CLEANUP_IN_PROGRESS` - Cleanup in Progress + * * `CLEANUP_COMPLETE` - Cleanup Complete + * * `CLEANUP_FAILED` - Cleanup Failed + * @enum {string} + */ + DeletionStatusEnum: "ACTIVE" | "CLEANUP_REQUESTED" | "CLEANUP_IN_PROGRESS" | "CLEANUP_COMPLETE" | "CLEANUP_FAILED"; + /** @description This is the serializer for create deploy API endpoint. */ + DeployCreate: { + /** @description Integer ID of the bundle to deploy or the string `current`, which re-deploys the currently deployed bundle */ + bundle_id: unknown; + }; + DeployList: { + /** + * Email address + * Format: email + */ + readonly user?: string; + bundle: components["schemas"]["BundleList"]; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + readonly status?: components["schemas"]["DeployListStatusEnum"]; + readonly deploy_type?: components["schemas"]["DeployTypeEnum"]; + /** + * Format: uuid + * @description Id for an external publishing operation for this Deploy + */ + external_publish_id?: string | null; + deploy_settings?: number | null; + duration: string; + }; + /** + * @description * `Queued` - Queued + * * `In Progress` - In Progress + * * `Failed` - Failed + * * `Finished` - Finished + * @enum {string} + */ + DeployListStatusEnum: "Queued" | "In Progress" | "Failed" | "Finished"; + /** + * @description * `Publish` - Publish + * * `Reset Bundle` - Reset Bundle + * * `Push` - Push + * * `Deploy Settings` - Deploy Settings + * * `Redeploy` - Redeploy + * @enum {string} + */ + DeployTypeEnum: "Publish" | "Reset Bundle" | "Push" | "Deploy Settings" | "Redeploy"; + EmailNotification: { + /** Format: uuid */ + readonly id?: string; + targets: string[]; + recipients: string[]; + /** @description Trigger this notification when a deployment starts for a target */ + deployment_start?: boolean; + /** @description Trigger this notification when a deployment succeeds for a target */ + deployment_success?: boolean; + /** @description Trigger this notification when a deployment fails for a target */ + deployment_failed?: boolean; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + /** + * Email address + * Format: email + */ + readonly updated_by?: string; + }; + EmailNotificationTyped: { + resourcetype: string; + } & components["schemas"]["EmailNotification"] & { + /** + * @description discriminator enum property added by openapi-typescript + * @enum {string} + */ + resourcetype: "EmailNotification"; + }; + /** + * @description * `base64` - base64 + * @enum {string} + */ + EncodingEnum: "base64"; + EnvironmentVariableList: { + /** @description Name of the Environment Variable. */ + name: string; + /** @description Value to be encrypted. */ + value: string; + /** + * Email address + * Format: email + */ + readonly created_by?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + /** + * Email address + * Format: email + */ + readonly updated_by?: string; + readonly publishing_status?: components["schemas"]["PublishingStatusEnum"]; + readonly publishing_status_description?: string; + }; + /** + * @description * `301` - Permanent 301 + * * `302` - Temporary 302 + * @enum {integer} + */ + HttpStatusCodeEnum: 301 | 302; + /** + * @description The minimum log level emitted for a target. + * @enum {string} + */ + LogLevelEnum: "TRACE" | "DEBUG" | "INFO" | "WARN" | "ERROR" | "FATAL"; + /** @enum {unknown} */ + NullEnum: null; + OrganizationAutoDelete: { + enabled: boolean; + threshold: number; + }; + OrganizationLimits: { + max_environments: components["schemas"]["ResourceLimit"]; + max_production_environments: components["schemas"]["ResourceLimit"]; + }; + PaginatedAPIAccessControlHeaderV2CreateList: { + /** @example 123 */ + count: number; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=400&limit=100 + */ + next?: string | null; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=200&limit=100 + */ + previous?: string | null; + results: components["schemas"]["APIAccessControlHeaderV2Create"][]; + }; + PaginatedAPIOrganizationList: { + /** @example 123 */ + count: number; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=400&limit=100 + */ + next?: string | null; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=200&limit=100 + */ + previous?: string | null; + results: components["schemas"]["APIOrganization"][]; + }; + PaginatedAPIProjectMemberList: { + /** @example 123 */ + count: number; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=400&limit=100 + */ + next?: string | null; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=200&limit=100 + */ + previous?: string | null; + results: components["schemas"]["APIProjectMember"][]; + }; + PaginatedAPIProjectV2CreateList: { + /** @example 123 */ + count: number; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=400&limit=100 + */ + next?: string | null; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=200&limit=100 + */ + previous?: string | null; + results: components["schemas"]["APIProjectV2Create"][]; + }; + PaginatedAPIRedirectV2CreateUpdateList: { + /** @example 123 */ + count: number; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=400&limit=100 + */ + next?: string | null; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=200&limit=100 + */ + previous?: string | null; + results: components["schemas"]["APIRedirectV2CreateUpdate"][]; + }; + PaginatedAPITargetV2CreateList: { + /** @example 123 */ + count: number; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=400&limit=100 + */ + next?: string | null; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=200&limit=100 + */ + previous?: string | null; + results: components["schemas"]["APITargetV2Create"][]; + }; + PaginatedBundleListList: { + /** @example 123 */ + count: number; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=400&limit=100 + */ + next?: string | null; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=200&limit=100 + */ + previous?: string | null; + results: components["schemas"]["BundleList"][]; + }; + PaginatedDeployListList: { + /** @example 123 */ + count: number; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=400&limit=100 + */ + next?: string | null; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=200&limit=100 + */ + previous?: string | null; + results: components["schemas"]["DeployList"][]; + }; + PaginatedEnvironmentVariableListList: { + /** @example 123 */ + count: number; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=400&limit=100 + */ + next?: string | null; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=200&limit=100 + */ + previous?: string | null; + results: components["schemas"]["EnvironmentVariableList"][]; + }; + PaginatedPolymorphicNotificationList: { + /** @example 123 */ + count: number; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=400&limit=100 + */ + next?: string | null; + /** + * Format: uri + * @example http://api.example.org/accounts/?offset=200&limit=100 + */ + previous?: string | null; + results: components["schemas"]["PolymorphicNotification"][]; + }; + PatchedAPIProjectMember: { + /** + * Email address + * Format: email + */ + user?: string; + role?: { + name?: string; + /** @enum {integer} */ + value?: 0 | 1 | 2 | 3; + }; + }; + PatchedAPIProjectV2Update: { + /** @description User-friendly name for this project */ + name?: string; + /** Format: uri */ + url?: string; + readonly slug?: string; + /** @description User-friendly identifier for this instance. */ + organization?: string; + readonly deletion_status?: components["schemas"]["DeletionStatusEnum"]; + readonly project_type?: components["schemas"]["ProjectTypeEnum"]; + readonly permissions?: { + browse?: boolean; + deploy?: boolean; + delete_bundle?: boolean; + delete_project?: boolean; + edit_redirect?: boolean; + edit_roles?: boolean; + edit_settings?: boolean; + validate_tag?: boolean; + edit_environment?: boolean; + create_environment?: boolean; + delete_environment?: boolean; + create_notification?: boolean; + list_notifications?: boolean; + retrieve_notification?: boolean; + edit_notification?: boolean; + delete_notification?: boolean; + create_jwt?: boolean; + upload_bundle?: boolean; + edit_environment_variable?: boolean; + edit_access_control_header?: boolean; + }; + /** + * SSR AWS Region + * @description The default AWS region for newly created targets + * + * * `us-east-1` - US East (N. Virginia) + * * `us-east-2` - US East (Ohio) + * * `us-west-1` - US West (N. California) + * * `us-west-2` - US West (Oregon) + * * `ap-south-1` - Asia Pacific (Mumbai) + * * `ap-south-2` - Asia Pacific (Hyderabad) + * * `ap-northeast-2` - Asia Pacific (Seoul) + * * `ap-southeast-1` - Asia Pacific (Singapore) + * * `ap-southeast-2` - Asia Pacific (Sydney) + * * `ap-southeast-3` - Asia Pacific (Jakarta) + * * `ap-northeast-1` - Asia Pacific (Tokyo) + * * `ap-northeast-3` - Asia Pacific (Osaka) + * * `ca-central-1` - Canada (Central) + * * `eu-central-1` - EU (Frankfurt) + * * `eu-central-2` - EU (Zurich) + * * `eu-west-1` - EU (Ireland) + * * `eu-west-2` - EU (London) + * * `eu-west-3` - EU (Paris) + * * `eu-north-1` - EU (Stockholm) + * * `eu-south-1` - EU (Milan) + * * `il-central-1` - Israel (Tel Aviv) + * * `me-central-1` - Middle East (UAE) + * * `sa-east-1` - South America (Sao Paulo) + */ + ssr_region?: components["schemas"]["SsrRegionEnum"]; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + }; + PatchedAPIRedirectV2CreateUpdate: { + /** @description A relative URL. For example, the `from_path` value `/spring` redirects shoppers from the URL `www.example.com/spring`. An asterisk (`*`) at the end of the `from_path` indicates a wildcard. For example, a redirect from `/a/*` matches `/a/`, `/a/b`, and `/a/b/c`. */ + from_path?: string; + /** @description A relative or absolute URL. For example, the `to_url` value `/summer` redirects shoppers to the URL `www.example.com/summer`. */ + to_url?: string; + /** @description Some requests contain query string parameters to include in the redirected request. For example, the relative path `/spring-landing-page` can be appended with a query string for analytics tracking, such as `/spring-landing-page?gclid=123`. The `true` value includes query string parameters in the redirect. The `false` value excludes query string parameters from the redirect. The default value is `false`. */ + forward_querystring?: boolean | null; + /** @description The `true` value automatically includes any path that comes after the wildcard portion of the `from_path` in the `to_url`. For example: if `/a/*` matches `/a/b/c` in the `from_path` and the `to_url` is `/z/`, the redirect URL is `/z/b/c`. The `false` value excludes the wildcard portion. The default value is `false`. */ + forward_wildcard?: boolean | null; + /** + * @description The HTTP status code to be returned in the response. 301 (Moved Permanently) is the recommended and default value. 302 (Found or Moved Temporarily) is another allowable value. For more information about HTTP status codes, see this [status code explainer](https://moz.com/learn/seo/redirection). + * + * * `301` - Permanent 301 + * * `302` - Temporary 302 + */ + http_status_code?: components["schemas"]["HttpStatusCodeEnum"]; + /** @description The status of the redeployment that happens after you call this API. Allowable values: Pending, Completed, Failed. If the request failed, you can [redeploy the environment](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/pushing-and-deploying-bundles.html) specified in your request. */ + readonly publishing_status?: string; + /** + * Email address + * Format: email + * @description Email of the user who created the redirect. + */ + readonly user_email?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + /** + * Email address + * Format: email + * @description Email of the user who last updated the redirect. + */ + readonly updated_by?: string; + }; + /** @description This is the base Target serializer. */ + PatchedAPITargetV2Update: { + readonly slug?: string; + /** @description User-friendly name for this target */ + name?: string; + /** + * @description Target State + * + * * `CREATE_IN_PROGRESS` - Create in Progress + * * `PUBLISH_IN_PROGRESS` - Publish in Progress + * * `ACTIVE` - Active + * * `CREATE_FAILED` - Create Failed + * * `PUBLISH_FAILED` - Publish Failed + */ + readonly state?: components["schemas"]["StateEnum"]; + readonly deletion_status?: components["schemas"]["DeletionStatusEnum"]; + /** @description Hostname (literal or JavaScript regular expression between / characters) on which this target should be loaded by the V8 Tag */ + hostname?: string | null; + readonly current_deploy?: { + [key: string]: unknown; + }; + /** @description Full hostname to used by the environment eg. www.customer.com. */ + ssr_external_hostname?: string | null; + /** @description The domain to be used for a Universal PWA SSR deployment (e.g. customer.com) */ + ssr_external_domain?: string | null; + /** + * SSR AWS Region + * @description The AWS region to which a Universal PWA SSR should be deployed (e.g. us-east-1) + * + * * `us-east-1` - US East (N. Virginia) + * * `us-east-2` - US East (Ohio) + * * `us-west-1` - US West (N. California) + * * `us-west-2` - US West (Oregon) + * * `ap-south-1` - Asia Pacific (Mumbai) + * * `ap-south-2` - Asia Pacific (Hyderabad) + * * `ap-northeast-2` - Asia Pacific (Seoul) + * * `ap-southeast-1` - Asia Pacific (Singapore) + * * `ap-southeast-2` - Asia Pacific (Sydney) + * * `ap-southeast-3` - Asia Pacific (Jakarta) + * * `ap-northeast-1` - Asia Pacific (Tokyo) + * * `ap-northeast-3` - Asia Pacific (Osaka) + * * `ca-central-1` - Canada (Central) + * * `eu-central-1` - EU (Frankfurt) + * * `eu-central-2` - EU (Zurich) + * * `eu-west-1` - EU (Ireland) + * * `eu-west-2` - EU (London) + * * `eu-west-3` - EU (Paris) + * * `eu-north-1` - EU (Stockholm) + * * `eu-south-1` - EU (Milan) + * * `il-central-1` - Israel (Tel Aviv) + * * `me-central-1` - Middle East (UAE) + * * `sa-east-1` - South America (Sao Paulo) + */ + ssr_region?: components["schemas"]["SsrRegionEnum"] | components["schemas"]["BlankEnum"]; + /** @description Optional space-separated list of IP addresses (CIDR blocks) that can access this target. Leave blank to allow all IPs. */ + ssr_whitelisted_ips?: string | null; + ssr_proxy_configs?: { + host: string; + protocol?: string; + }[] | null; + /** + * Production + * @description Treat this target as a production environment. + */ + is_production?: boolean; + /** @description Set true to forward the HTTP cookie header sent by clients to your origin and ensure the Set-Cookie header sent by your app is respected and not stripped. */ + allow_cookies?: boolean | null; + /** @description Set true to enable source map support. This will set the NODE_OPTIONS environment variable to "--enable-source-maps" in your MRT environment. */ + enable_source_maps?: boolean | null; + /** + * @description The minimum log level emitted for this target. + * + * * `TRACE` + * * `DEBUG` + * * `INFO` + * * `WARN` + * * `ERROR` + * * `FATAL` + */ + log_level?: (components["schemas"]["LogLevelEnum"] | components["schemas"]["NullEnum"]) | null; + }; + PatchedEmailNotification: { + /** Format: uuid */ + readonly id?: string; + targets?: string[]; + recipients?: string[]; + /** @description Trigger this notification when a deployment starts for a target */ + deployment_start?: boolean; + /** @description Trigger this notification when a deployment succeeds for a target */ + deployment_success?: boolean; + /** @description Trigger this notification when a deployment fails for a target */ + deployment_failed?: boolean; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + /** + * Email address + * Format: email + */ + readonly updated_by?: string; + }; + PatchedEmailNotificationTyped: { + resourcetype?: string; + } & components["schemas"]["PatchedEmailNotification"] & { + /** + * @description discriminator enum property added by openapi-typescript + * @enum {string} + */ + resourcetype: "EmailNotification"; + }; + PatchedPolymorphicNotification: components["schemas"]["PatchedEmailNotificationTyped"]; + PatchedUserEmailPreferences: { + /** @description The user's email notification preferences for Node.js runtime's deprecation and retirement. */ + node_deprecation_notifications?: boolean; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + }; + PolymorphicNotification: components["schemas"]["EmailNotificationTyped"]; + /** + * @description * `MOBIFY_STUDIO` - MOBIFY_STUDIO + * * `MOBIFYJS_CLIENT` - MOBIFYJS_CLIENT + * * `MOBIFY_ADAPTIVEJS` - MOBIFY_ADAPTIVEJS + * * `MOBIFY_TAG_BASED_PWA` - MOBIFY_TAG_BASED_PWA + * * `SSR` - SSR + * @enum {string} + */ + ProjectTypeEnum: "MOBIFY_STUDIO" | "MOBIFYJS_CLIENT" | "MOBIFY_ADAPTIVEJS" | "MOBIFY_TAG_BASED_PWA" | "SSR"; + /** + * @description * `0` - Pending + * * `1` - Completed + * * `2` - Failed + * @enum {integer} + */ + PublishingStatusEnum: 0 | 1 | 2; + ResourceLimit: { + limit: number; + used: number; + }; + /** + * @description * `us-east-1` - US East (N. Virginia) + * * `us-east-2` - US East (Ohio) + * * `us-west-1` - US West (N. California) + * * `us-west-2` - US West (Oregon) + * * `ap-south-1` - Asia Pacific (Mumbai) + * * `ap-south-2` - Asia Pacific (Hyderabad) + * * `ap-northeast-2` - Asia Pacific (Seoul) + * * `ap-southeast-1` - Asia Pacific (Singapore) + * * `ap-southeast-2` - Asia Pacific (Sydney) + * * `ap-southeast-3` - Asia Pacific (Jakarta) + * * `ap-northeast-1` - Asia Pacific (Tokyo) + * * `ap-northeast-3` - Asia Pacific (Osaka) + * * `ca-central-1` - Canada (Central) + * * `eu-central-1` - EU (Frankfurt) + * * `eu-central-2` - EU (Zurich) + * * `eu-west-1` - EU (Ireland) + * * `eu-west-2` - EU (London) + * * `eu-west-3` - EU (Paris) + * * `eu-north-1` - EU (Stockholm) + * * `eu-south-1` - EU (Milan) + * * `il-central-1` - Israel (Tel Aviv) + * * `me-central-1` - Middle East (UAE) + * * `sa-east-1` - South America (Sao Paulo) + * @enum {string} + */ + SsrRegionEnum: "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2" | "ap-south-1" | "ap-south-2" | "ap-northeast-2" | "ap-southeast-1" | "ap-southeast-2" | "ap-southeast-3" | "ap-northeast-1" | "ap-northeast-3" | "ca-central-1" | "eu-central-1" | "eu-central-2" | "eu-west-1" | "eu-west-2" | "eu-west-3" | "eu-north-1" | "eu-south-1" | "il-central-1" | "me-central-1" | "sa-east-1"; + /** + * @description * `CREATE_IN_PROGRESS` - Create in Progress + * * `PUBLISH_IN_PROGRESS` - Publish in Progress + * * `ACTIVE` - Active + * * `CREATE_FAILED` - Create Failed + * * `PUBLISH_FAILED` - Publish Failed + * @enum {string} + */ + StateEnum: "CREATE_IN_PROGRESS" | "PUBLISH_IN_PROGRESS" | "ACTIVE" | "CREATE_FAILED" | "PUBLISH_FAILED"; + /** + * @description * `0` - ok + * * `1` - broken + * * `2` - preparing + * @enum {integer} + */ + Status1d2Enum: 0 | 1 | 2; + UserEmailPreferences: { + /** @description The user's email notification preferences for Node.js runtime's deprecation and retirement. */ + node_deprecation_notifications?: boolean; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was created. + */ + readonly created_at?: string; + /** + * Format: date-time + * @description Timestamp in the extended ISO 8601 format for when the object was last updated. + */ + readonly updated_at?: string; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +} +export type $defs = Record; +export interface operations { + organizations_list: { + parameters: { + query?: { + /** @description Number of results to return per page. */ + limit?: number; + /** @description The initial index from which to return the results. */ + offset?: number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PaginatedAPIOrganizationList"]; + }; + }; + }; + }; + projects_list: { + parameters: { + query?: { + /** @description Number of results to return per page. */ + limit?: number; + /** @description The initial index from which to return the results. */ + offset?: number; + /** @description An organization to search within. */ + organization?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PaginatedAPIProjectV2CreateList"]; + }; + }; + }; + }; + projects_create: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["APIProjectV2Create"]; + "application/x-www-form-urlencoded": components["schemas"]["APIProjectV2Create"]; + "multipart/form-data": components["schemas"]["APIProjectV2Create"]; + }; + }; + responses: { + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIProjectV2Create"]; + }; + }; + }; + }; + projects_retrieve: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIProjectV2Update"]; + }; + }; + }; + }; + projects_destroy: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description No response body */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + projects_partial_update: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["PatchedAPIProjectV2Update"]; + "application/x-www-form-urlencoded": components["schemas"]["PatchedAPIProjectV2Update"]; + "multipart/form-data": components["schemas"]["PatchedAPIProjectV2Update"]; + }; + }; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIProjectV2Update"]; + }; + }; + }; + }; + projects_builds_create: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["Bundle"]; + "application/x-www-form-urlencoded": components["schemas"]["Bundle"]; + "multipart/form-data": components["schemas"]["Bundle"]; + }; + }; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": { + [key: string]: unknown; + }; + }; + }; + }; + }; + projects_builds_create_and_deploy: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["Bundle"]; + "application/x-www-form-urlencoded": components["schemas"]["Bundle"]; + "multipart/form-data": components["schemas"]["Bundle"]; + }; + }; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": { + [key: string]: unknown; + }; + }; + }; + }; + }; + projects_bundles_list: { + parameters: { + query?: { + /** @description Number of results to return per page. */ + limit?: number; + /** @description The initial index from which to return the results. */ + offset?: number; + /** @description A search term. */ + search?: string; + }; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PaginatedBundleListList"]; + }; + }; + }; + }; + projects_bundles_download_retrieve: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The bundle's id */ + bundle_id: string; + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BundleDownload"]; + }; + }; + }; + }; + projects_members_list: { + parameters: { + query?: { + /** @description Number of results to return per page. */ + limit?: number; + /** @description The initial index from which to return the results. */ + offset?: number; + /** @description Which field to use when ordering the results. */ + ordering?: string; + /** + * @description * `0` - Admin + * * `1` - Developer + * * `2` - Marketer + * * `3` - Read Only + * + * * `0` - Admin + * * `1` - Developer + * * `2` - Marketer + * * `3` - Read Only + */ + role?: 0 | 1 | 2 | 3; + /** @description A search term. */ + search?: string; + }; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description A role to filter on. Admin=0, Developer=1, Marketer=2, Read Only=3. */ + role: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PaginatedAPIProjectMemberList"]; + }; + }; + }; + }; + projects_members_create: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["APIProjectMember"]; + "application/x-www-form-urlencoded": components["schemas"]["APIProjectMember"]; + "multipart/form-data": components["schemas"]["APIProjectMember"]; + }; + }; + responses: { + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIProjectMember"]; + }; + }; + }; + }; + projects_members_retrieve: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project member's email address. */ + email: string; + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIProjectMember"]; + }; + }; + }; + }; + projects_members_destroy: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project member's email address. */ + email: string; + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description No response body */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + projects_members_partial_update: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project member's email address. */ + email: string; + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["PatchedAPIProjectMember"]; + "application/x-www-form-urlencoded": components["schemas"]["PatchedAPIProjectMember"]; + "multipart/form-data": components["schemas"]["PatchedAPIProjectMember"]; + }; + }; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIProjectMember"]; + }; + }; + }; + }; + projects_notifications_list: { + parameters: { + query?: { + /** @description Number of results to return per page. */ + limit?: number; + /** @description The initial index from which to return the results. */ + offset?: number; + targets__slug?: string; + }; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PaginatedPolymorphicNotificationList"]; + }; + }; + }; + }; + projects_notifications_create: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["PolymorphicNotification"]; + "application/x-www-form-urlencoded": components["schemas"]["PolymorphicNotification"]; + "multipart/form-data": components["schemas"]["PolymorphicNotification"]; + }; + }; + responses: { + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PolymorphicNotification"]; + }; + }; + }; + }; + projects_notifications_retrieve: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The notification's unique UUID */ + id: string; + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PolymorphicNotification"]; + }; + }; + }; + }; + projects_notifications_destroy: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The notification's unique UUID */ + id: string; + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description No response body */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + projects_notifications_partial_update: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The notification's unique UUID */ + id: string; + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["PatchedPolymorphicNotification"]; + "application/x-www-form-urlencoded": components["schemas"]["PatchedPolymorphicNotification"]; + "multipart/form-data": components["schemas"]["PatchedPolymorphicNotification"]; + }; + }; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PolymorphicNotification"]; + }; + }; + }; + }; + projects_target_list: { + parameters: { + query?: { + /** @description Number of results to return per page. */ + limit?: number; + /** @description The initial index from which to return the results. */ + offset?: number; + /** @description Which field to use when ordering the results. */ + ordering?: string; + /** @description A search term. */ + search?: string; + }; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PaginatedAPITargetV2CreateList"]; + }; + }; + }; + }; + projects_target_create: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["APITargetV2Create"]; + "application/x-www-form-urlencoded": components["schemas"]["APITargetV2Create"]; + "multipart/form-data": components["schemas"]["APITargetV2Create"]; + }; + }; + responses: { + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APITargetV2Create"]; + }; + }; + }; + }; + projects_target_retrieve: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APITargetV2Update"]; + }; + }; + }; + }; + projects_target_destroy: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description No response body */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + projects_target_partial_update: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["PatchedAPITargetV2Update"]; + "application/x-www-form-urlencoded": components["schemas"]["PatchedAPITargetV2Update"]; + "multipart/form-data": components["schemas"]["PatchedAPITargetV2Update"]; + }; + }; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APITargetV2Update"]; + }; + }; + }; + }; + projects_target_access_control_header_list: { + parameters: { + query?: { + /** @description Number of results to return per page. */ + limit?: number; + /** @description The initial index from which to return the results. */ + offset?: number; + /** @description Which field to use when ordering the results. */ + ordering?: string; + /** @description A search term. */ + search?: string; + }; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PaginatedAPIAccessControlHeaderV2CreateList"]; + }; + }; + }; + }; + projects_target_access_control_header_create: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["APIAccessControlHeaderV2Create"]; + "application/x-www-form-urlencoded": components["schemas"]["APIAccessControlHeaderV2Create"]; + "multipart/form-data": components["schemas"]["APIAccessControlHeaderV2Create"]; + }; + }; + responses: { + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIAccessControlHeaderV2Create"]; + }; + }; + }; + }; + projects_target_access_control_header_retrieve: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The access control header's id. */ + id: string; + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIAccessControlHeaderV2Create"]; + }; + }; + }; + }; + projects_target_access_control_header_destroy: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The access control header's id. */ + id: string; + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description No response body */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + projects_target_deploy_list: { + parameters: { + query?: { + /** @description Number of results to return per page. */ + limit?: number; + /** @description The initial index from which to return the results. */ + offset?: number; + }; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PaginatedDeployListList"]; + }; + }; + }; + }; + projects_target_deploy_create: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DeployCreate"]; + "application/x-www-form-urlencoded": components["schemas"]["DeployCreate"]; + "multipart/form-data": components["schemas"]["DeployCreate"]; + }; + }; + responses: { + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DeployCreate"]; + }; + }; + }; + }; + projects_target_env_var_list: { + parameters: { + query?: { + /** @description Number of results to return per page. */ + limit?: number; + /** @description The initial index from which to return the results. */ + offset?: number; + /** @description Which field to use when ordering the results. */ + ordering?: string; + /** @description A search term. */ + search?: string; + }; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PaginatedEnvironmentVariableListList"]; + }; + }; + }; + }; + projects_target_env_var_partial_update: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": { + [key: string]: unknown; + }; + "application/x-www-form-urlencoded": { + [key: string]: unknown; + }; + "multipart/form-data": { + [key: string]: unknown; + }; + }; + }; + responses: { + /** @description No response body. The request was processed successfully. */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + projects_target_invalidation_create: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["APITargetV2CreateInvalidation"]; + "application/x-www-form-urlencoded": components["schemas"]["APITargetV2CreateInvalidation"]; + "multipart/form-data": components["schemas"]["APITargetV2CreateInvalidation"]; + }; + }; + responses: { + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APITargetV2CreateInvalidation"]; + }; + }; + }; + }; + projects_target_redirect_list: { + parameters: { + query?: { + /** @description Number of results to return per page. */ + limit?: number; + /** @description The initial index from which to return the results. */ + offset?: number; + /** @description Which field to use when ordering the results. */ + ordering?: string; + /** @description A search term. */ + search?: string; + }; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PaginatedAPIRedirectV2CreateUpdateList"]; + }; + }; + }; + }; + projects_target_redirect_create: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["APIRedirectV2CreateUpdate"]; + "application/x-www-form-urlencoded": components["schemas"]["APIRedirectV2CreateUpdate"]; + "multipart/form-data": components["schemas"]["APIRedirectV2CreateUpdate"]; + }; + }; + responses: { + /** @description The request was processed successfully. */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIRedirectV2CreateUpdate"]; + }; + }; + }; + }; + projects_target_redirect_retrieve: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The redirect's `from_path`. */ + from_path: string; + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIRedirectV2CreateUpdate"]; + }; + }; + }; + }; + projects_target_redirect_destroy: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The redirect's `from_path`. */ + from_path: string; + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description No response body. The request was processed successfully. */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + projects_target_redirect_partial_update: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The redirect's `from_path`. */ + from_path: string; + /** @description The project identifier. */ + project_slug: string; + /** @description The target identifier. */ + target_slug: string; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["PatchedAPIRedirectV2CreateUpdate"]; + "application/x-www-form-urlencoded": components["schemas"]["PatchedAPIRedirectV2CreateUpdate"]; + "multipart/form-data": components["schemas"]["PatchedAPIRedirectV2CreateUpdate"]; + }; + }; + responses: { + /** @description The request was processed successfully. */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIRedirectV2CreateUpdate"]; + }; + }; + }; + }; + projects_target_redirect_clone_create: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The project identifier. */ + project_slug: string; + /** @description The destination target identifier for the clone operation. */ + to_target_slug: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["APIRedirectV2Clone"]; + "application/x-www-form-urlencoded": components["schemas"]["APIRedirectV2Clone"]; + "multipart/form-data": components["schemas"]["APIRedirectV2Clone"]; + }; + }; + responses: { + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIRedirectV2Clone"]; + }; + }; + }; + }; + users_me_api_key_create: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": { + [key: string]: unknown; + }; + }; + }; + }; + }; + users_me_email_preferences_retrieve: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["UserEmailPreferences"]; + }; + }; + }; + }; + users_me_email_preferences_partial_update: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["PatchedUserEmailPreferences"]; + "application/x-www-form-urlencoded": components["schemas"]["PatchedUserEmailPreferences"]; + "multipart/form-data": components["schemas"]["PatchedUserEmailPreferences"]; + }; + }; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["UserEmailPreferences"]; + }; + }; + }; + }; + users_me_profile_retrieve: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIUserProfile"]; + }; + }; + }; + }; +} diff --git a/packages/b2c-tooling/src/clients/mrt.ts b/packages/b2c-tooling/src/clients/mrt.ts new file mode 100644 index 00000000..16f73c0b --- /dev/null +++ b/packages/b2c-tooling/src/clients/mrt.ts @@ -0,0 +1,137 @@ +/** + * Managed Runtime (MRT) API client for B2C Commerce. + * + * Provides a fully typed client for Managed Runtime API operations using + * openapi-fetch with API key authentication middleware. Used for + * managing deployments, bundles, projects, and environments. + * + * @module clients/mrt + */ +import createClient, {type Client} from 'openapi-fetch'; +import type {AuthStrategy} from '../auth/types.js'; +import type {paths, components} from './mrt.generated.js'; +import {createAuthMiddleware, createLoggingMiddleware} from './middleware.js'; + +/** + * Re-export generated types for external use. + */ +export type {paths, components}; + +/** + * The typed MRT client - this is the openapi-fetch Client with full type safety. + * + * @see {@link createMrtClient} for instantiation + */ +export type MrtClient = Client; + +/** + * Helper type to extract response data from an operation. + */ +export type MrtResponse = T extends {content: {'application/json': infer R}} ? R : never; + +/** + * Standard MRT error response structure. + */ +export interface MrtError { + status: number; + message: string; + detail?: string; +} + +/** + * Response from pushing a bundle to MRT. + * + * Note: The OpenAPI spec doesn't properly define this response type, + * so we define it based on the actual API response. + */ +export interface BuildPushResponse { + /** The bundle ID assigned by MRT */ + bundle_id: number; + /** Success message from the API */ + message: string; + /** URL to view the bundle in the MRT dashboard */ + url: string; + /** Preview URL for the bundle (if available) */ + bundle_preview_url: string | null; + /** Any warnings from the push operation */ + warnings: string[]; +} + +/** + * Configuration for creating an MRT client. + */ +export interface MrtClientConfig { + /** + * The origin URL for the MRT API. + * @default "https://cloud.mobify.com" + * @example "https://cloud.mobify.com" + */ + origin?: string; +} + +/** + * Default MRT API origin. + */ +export const DEFAULT_MRT_ORIGIN = 'https://cloud.mobify.com'; + +/** + * Creates a typed Managed Runtime API client. + * + * Returns the openapi-fetch client directly, with authentication + * handled via middleware. This gives full access to all openapi-fetch + * features with type-safe paths, parameters, and responses. + * + * @param config - MRT client configuration + * @param auth - Authentication strategy (typically ApiKeyStrategy) + * @returns Typed openapi-fetch client + * + * @example + * // Create MRT client with API key auth + * const apiKeyStrategy = new ApiKeyStrategy(apiKey, 'Authorization'); + * + * const client = createMrtClient({}, apiKeyStrategy); + * + * // Push a bundle to a project + * const { data, error } = await client.POST('/api/projects/{projectSlug}/builds/', { + * params: { + * path: { projectSlug: 'my-project' } + * }, + * body: { + * message: 'My bundle', + * encoding: 'base64', + * data: bundleData, + * ssr_parameters: {}, + * ssr_only: ['ssr.js'], + * ssr_shared: ['shared.js'] + * } + * }); + * + * @example + * // List all projects + * const { data, error } = await client.GET('/api/projects/', {}); + * + * @example + * // Get a specific target/environment + * const { data, error } = await client.GET('/api/projects/{projectSlug}/target/{targetId}/', { + * params: { path: { projectSlug: 'my-project', targetId: 'staging' } } + * }); + */ +export function createMrtClient(config: MrtClientConfig, auth: AuthStrategy): MrtClient { + const origin = config.origin || DEFAULT_MRT_ORIGIN; + + const client = createClient({ + baseUrl: origin, + }); + + // Middleware order: auth → logging (logging sees fully modified request) + client.use(createAuthMiddleware(auth)); + client.use( + createLoggingMiddleware({ + prefix: 'MRT', + // Mask large base64-encoded bundle data in logs + maskBodyKeys: ['data'], + }), + ); + + return client; +} diff --git a/packages/b2c-tooling/src/operations/jobs/site-archive.ts b/packages/b2c-tooling/src/operations/jobs/site-archive.ts index 6a57f1e8..5b02e6b1 100644 --- a/packages/b2c-tooling/src/operations/jobs/site-archive.ts +++ b/packages/b2c-tooling/src/operations/jobs/site-archive.ts @@ -9,14 +9,7 @@ import * as path from 'node:path'; import JSZip from 'jszip'; import {B2CInstance} from '../../instance/index.js'; import {getLogger} from '../../logging/logger.js'; -import { - executeJob, - waitForJob, - JobExecutionError, - getJobLog, - type JobExecution, - type WaitForJobOptions, -} from './run.js'; +import {waitForJob, JobExecutionError, getJobLog, type JobExecution, type WaitForJobOptions} from './run.js'; const IMPORT_JOB_ID = 'sfcc-site-archive-import'; const EXPORT_JOB_ID = 'sfcc-site-archive-export'; @@ -138,54 +131,34 @@ export async function siteArchiveImport( logger.debug(`Archive uploaded: ${uploadPath}`); } - // Execute the import job - logger.debug(`Executing ${IMPORT_JOB_ID} job`); + // Execute the import job with file_name parameter + logger.debug(`Executing ${IMPORT_JOB_ID} job with file_name: ${zipFilename}`); let execution: JobExecution; - try { - // Try the standard form first (external users) - execution = await executeJob(instance, IMPORT_JOB_ID, { - parameters: [], - waitForRunning: true, - }); - - // The job needs the file_name - try with parameters form - // Different SFCC versions accept different formats - } catch (error) { - // If we get UnknownPropertyException, try the parameters format - if (error instanceof Error && error.message.includes('UnknownPropertyException')) { - logger.warn('Using parameters format for import job'); - } - throw error; - } - - // Execute with the correct format - try file_name first, then parameters - try { - const {data, error} = await instance.ocapi.POST('/jobs/{job_id}/executions', { - params: {path: {job_id: IMPORT_JOB_ID}}, - body: {file_name: zipFilename} as unknown as string, - }); - if (error || !data) { - throw new Error(error?.fault?.message ?? 'Failed to execute import job'); - } + // Try file_name format first (standard OCAPI format) + const {data, error} = await instance.ocapi.POST('/jobs/{job_id}/executions', { + params: {path: {job_id: IMPORT_JOB_ID}}, + body: {file_name: zipFilename} as unknown as string, + }); - execution = data; - } catch { - // Try with parameters format for internal users + if (error || !data) { + // Try with parameters format as fallback logger.warn('Retrying with parameters format for internal users'); - const {data, error} = await instance.ocapi.POST('/jobs/{job_id}/executions', { + const {data: retryData, error: retryError} = await instance.ocapi.POST('/jobs/{job_id}/executions', { params: {path: {job_id: IMPORT_JOB_ID}}, body: { parameters: [{name: 'ImportFile', value: zipFilename}], } as unknown as string, }); - if (error || !data) { - throw new Error(error?.fault?.message ?? 'Failed to execute import job'); + if (retryError || !retryData) { + throw new Error(retryError?.fault?.message ?? error?.fault?.message ?? 'Failed to execute import job'); } + execution = retryData; + } else { execution = data; } diff --git a/packages/b2c-tooling/src/operations/mrt/bundle.ts b/packages/b2c-tooling/src/operations/mrt/bundle.ts new file mode 100644 index 00000000..445538fc --- /dev/null +++ b/packages/b2c-tooling/src/operations/mrt/bundle.ts @@ -0,0 +1,269 @@ +/** + * Bundle creation utilities for Managed Runtime. + * + * Creates tar archives for deployment to Managed Runtime. + * Based on the bundle format expected by the MRT API. + * + * @module operations/mrt/bundle + */ +import {createWriteStream} from 'node:fs'; +import {readFile, stat, mkdtemp, rm} from 'node:fs/promises'; +import path from 'node:path'; +import os from 'node:os'; +import archiver from 'archiver'; +import {Minimatch} from 'minimatch'; +import {getLogger} from '../../logging/logger.js'; +import type {Stats} from 'node:fs'; + +/** + * Default SSR parameters applied to all bundles. + * These can be overridden by providing ssrParameters in CreateBundleOptions. + */ +export const DEFAULT_SSR_PARAMETERS: Record = { + /** + * Node.js version for the SSR function runtime. + * @see https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/upgrading-node-version.html + */ + SSRFunctionNodeVersion: '22.x', +}; + +/** + * Configuration for bundle creation. + */ +export interface CreateBundleOptions { + /** + * Optional message describing the bundle. + * Defaults to a git-based message or a timestamp. + */ + message?: string; + + /** + * SSR parameters to include in the bundle. + * These are configuration values for the SSR runtime. + */ + ssrParameters?: Record; + + /** + * Glob patterns for files that should only run on the server. + * @example ['ssr.js', 'ssr/*.js'] + */ + ssrOnly: string[]; + + /** + * Glob patterns for files shared between client and server. + * @example ['static/**\/*', '**\/*.js'] + */ + ssrShared: string[]; + + /** + * Path to the build directory containing the application build output. + * @default 'build' + */ + buildDirectory?: string; + + /** + * Project slug for the MRT project. + * Used to prefix files in the archive. + */ + projectSlug: string; +} + +/** + * A bundle ready for upload to Managed Runtime. + */ +export interface Bundle { + /** + * Message describing the bundle. + */ + message: string; + + /** + * Encoding of the data field. + */ + encoding: 'base64'; + + /** + * Base64-encoded tar archive of the build. + */ + data: string; + + /** + * SSR parameters configuration. + */ + ssr_parameters: Record; + + /** + * List of files that only run on the server. + */ + ssr_only: string[]; + + /** + * List of files shared between client and server. + */ + ssr_shared: string[]; + + /** + * Bundle metadata including dependencies. + */ + bundle_metadata?: Record; +} + +/** + * Creates a glob filter function from patterns. + * + * Patterns can include negations (prefixed with !). + * A path matches if it matches any positive pattern + * and does not match any negative pattern. + * + * @param patterns - Glob patterns to match against + * @returns Filter function that returns true for matching paths + */ +export function createGlobFilter(patterns?: string[]): (path: string) => boolean { + const allPatterns = (patterns || []) + .map((pattern) => new Minimatch(pattern, {nocomment: true})) + .filter((pattern) => !pattern.empty); + + const positivePatterns = allPatterns.filter((pattern) => !pattern.negate); + const negativePatterns = allPatterns.filter((pattern) => pattern.negate); + + return (filePath: string) => { + if (!filePath) return false; + const positive = positivePatterns.some((pattern) => pattern.match(filePath)); + const negative = negativePatterns.some((pattern) => !pattern.match(filePath)); + return positive && !negative; + }; +} + +/** + * Gets a default bundle message with timestamp. + * + * @returns A message like "Bundle 2025-01-15T10:30:00.000Z" + */ +export function getDefaultMessage(): string { + return `Bundle ${new Date().toISOString()}`; +} + +/** + * Creates a bundle from a build directory. + * + * This creates a tar archive of the build directory, base64 encodes it, + * and returns a bundle object ready for upload to Managed Runtime. + * + * The archive structure is: `{projectSlug}/bld/{files...}` + * + * @param options - Bundle creation options + * @returns Bundle object ready for upload + * @throws Error if build directory doesn't exist or ssr patterns are empty + * + * @example + * ```typescript + * const bundle = await createBundle({ + * projectSlug: 'my-project', + * ssrOnly: ['ssr.js'], + * ssrShared: ['**\/*.js', 'static/**\/*'], + * buildDirectory: './build', + * message: 'Release v1.0.0' + * }); + * ``` + */ +export async function createBundle(options: CreateBundleOptions): Promise { + const logger = getLogger(); + const {ssrOnly, ssrShared, projectSlug} = options; + const buildDirectory = options.buildDirectory || 'build'; + const message = options.message || getDefaultMessage(); + + // Merge default SSR parameters with provided ones (provided values take precedence) + const ssrParameters = { + ...DEFAULT_SSR_PARAMETERS, + ...options.ssrParameters, + }; + + logger.debug({projectSlug, buildDirectory, ssrParameters}, '[MRT] Creating bundle'); + + // Validate SSR patterns + if (ssrOnly.length === 0 || ssrShared.length === 0) { + throw new Error('ssrOnly and ssrShared patterns are required and cannot be empty'); + } + + // Verify build directory exists + const buildPath = path.isAbsolute(buildDirectory) ? buildDirectory : path.join(process.cwd(), buildDirectory); + + try { + await stat(buildPath); + } catch { + throw new Error( + `Build directory at path "${buildPath}" not found.\n` + 'Ensure your project has been built first.', + ); + } + + // Create temp directory for tar file + const tmpDir = await mkdtemp(path.join(os.tmpdir(), 'b2c-mrt-')); + const tarPath = path.join(tmpDir, 'build.tar'); + const filesInArchive: string[] = []; + + try { + // Create tar archive + await new Promise((resolve, reject) => { + const output = createWriteStream(tarPath); + const archive = archiver('tar'); + + archive.pipe(output); + + // Prefix all files with {projectSlug}/bld/ + const newRoot = path.join(projectSlug, 'bld', ''); + + archive.directory(buildPath, false, (entry) => { + const stats = entry.stats as Stats | undefined; + if (stats?.isFile() && entry.name) { + filesInArchive.push(entry.name); + } + entry.prefix = newRoot; + return entry; + }); + + archive.on('error', reject); + output.on('finish', resolve); + + archive.finalize(); + }); + + logger.debug({fileCount: filesInArchive.length}, '[MRT] Archive created'); + logger.trace({files: filesInArchive.slice(0, 20)}, '[MRT] First 20 files in archive'); + + // Read and encode the tar file + const tarData = await readFile(tarPath); + const base64Data = tarData.toString('base64'); + + // Filter files for ssr_only and ssr_shared + logger.trace({ssrOnly, ssrShared}, '[MRT] SSR patterns'); + const ssrOnlyFilter = createGlobFilter(ssrOnly); + const ssrSharedFilter = createGlobFilter(ssrShared); + + const ssrOnlyFiles = filesInArchive.filter(ssrOnlyFilter); + const ssrSharedFiles = filesInArchive.filter(ssrSharedFilter); + + logger.trace({ssrOnlyFiles: ssrOnlyFiles.slice(0, 20)}, '[MRT] First 20 ssr_only files'); + logger.trace({ssrSharedFiles: ssrSharedFiles.slice(0, 20)}, '[MRT] First 20 ssr_shared files'); + + logger.debug( + { + ssrOnlyCount: ssrOnlyFiles.length, + ssrSharedCount: ssrSharedFiles.length, + totalSize: base64Data.length, + }, + '[MRT] Bundle created', + ); + + return { + message, + encoding: 'base64', + data: base64Data, + ssr_parameters: ssrParameters, + ssr_only: ssrOnlyFiles, + ssr_shared: ssrSharedFiles, + }; + } finally { + // Clean up temp directory + await rm(tmpDir, {recursive: true}).catch(() => {}); + } +} diff --git a/packages/b2c-tooling/src/operations/mrt/env-var.ts b/packages/b2c-tooling/src/operations/mrt/env-var.ts new file mode 100644 index 00000000..dae40ca3 --- /dev/null +++ b/packages/b2c-tooling/src/operations/mrt/env-var.ts @@ -0,0 +1,339 @@ +/** + * Environment variable operations for Managed Runtime. + * + * Handles listing, setting, and deleting environment variables + * on MRT project environments. + * + * @module operations/mrt/env-var + */ +import type {AuthStrategy} from '../../auth/types.js'; +import {createMrtClient, DEFAULT_MRT_ORIGIN} from '../../clients/mrt.js'; +import {getLogger} from '../../logging/logger.js'; + +/** + * Environment variable information returned from MRT. + */ +export interface EnvironmentVariable { + /** Name of the environment variable */ + name: string; + /** Masked value (only last few characters visible) */ + value: string; + /** Email of user who created the variable */ + createdBy: string; + /** ISO timestamp when created */ + createdAt: string; + /** ISO timestamp when last updated */ + updatedAt: string; + /** Email of user who last updated the variable */ + updatedBy: string; + /** Publishing status code */ + publishingStatus: number; + /** Human-readable publishing status */ + publishingStatusDescription: string; +} + +/** + * Result of listing environment variables. + */ +export interface ListEnvVarsResult { + /** Total count of environment variables */ + count: number; + /** Environment variables */ + variables: EnvironmentVariable[]; +} + +/** + * Options for environment variable operations. + */ +export interface EnvVarOptions { + /** MRT project slug */ + projectSlug: string; + /** Target environment (e.g., 'staging', 'production') */ + environment: string; + /** + * MRT API origin URL. + * @default "https://cloud.mobify.com" + */ + origin?: string; +} + +/** + * Lists environment variables for a project environment. + * + * @param options - Options specifying project and environment + * @param auth - Authentication strategy (ApiKeyStrategy) + * @returns List of environment variables + * @throws Error if request fails + * + * @example + * ```typescript + * import { ApiKeyStrategy } from '@salesforce/b2c-tooling/auth'; + * import { listEnvVars } from '@salesforce/b2c-tooling/operations/mrt'; + * + * const auth = new ApiKeyStrategy(process.env.MRT_API_KEY!, 'Authorization'); + * + * const result = await listEnvVars({ + * projectSlug: 'my-storefront', + * environment: 'production' + * }, auth); + * + * for (const envVar of result.variables) { + * console.log(`${envVar.name}=${envVar.value}`); + * } + * ``` + */ +export async function listEnvVars(options: EnvVarOptions, auth: AuthStrategy): Promise { + const logger = getLogger(); + const {projectSlug, environment, origin} = options; + + logger.debug({projectSlug, environment}, '[MRT] Listing environment variables'); + + const client = createMrtClient({origin: origin || DEFAULT_MRT_ORIGIN}, auth); + + const {data, error} = await client.GET('/api/projects/{project_slug}/target/{target_slug}/env-var/', { + params: { + path: { + project_slug: projectSlug, + target_slug: environment, + }, + }, + }); + + if (error) { + throw new Error(`Failed to list environment variables: ${JSON.stringify(error)}`); + } + + // The API can return two formats: + // 1. Paginated: { count, next, previous, results: [{ "VAR_NAME": {...} }, ...] } + // 2. Direct object: { "VAR_NAME": {...}, "VAR_NAME2": {...}, ... } + const variables: EnvironmentVariable[] = []; + const responseData = data as Record; + + // Check if it's the paginated format (has 'results' array) + if (responseData?.results && Array.isArray(responseData.results)) { + for (const item of responseData.results as Record[]) { + const entries = Object.entries(item); + for (const [name, metadata] of entries) { + const meta = metadata as Record; + variables.push(parseEnvVarMetadata(name, meta)); + } + } + } else if (responseData) { + // Direct object format - each key is an env var name (skip pagination fields) + const paginationFields = ['count', 'next', 'previous', 'results']; + for (const [name, metadata] of Object.entries(responseData)) { + if (paginationFields.includes(name)) continue; + const meta = metadata as Record; + // Verify it looks like env var metadata (has 'value' property) + if (meta && typeof meta === 'object' && 'value' in meta) { + variables.push(parseEnvVarMetadata(name, meta)); + } + } + } + + logger.debug({count: variables.length}, '[MRT] Listed environment variables'); + + return { + count: typeof responseData?.count === 'number' ? responseData.count : variables.length, + variables, + }; +} + +/** + * Parses environment variable metadata from API response. + */ +function parseEnvVarMetadata(name: string, meta: Record): EnvironmentVariable { + return { + name, + value: String(meta.value ?? ''), + createdBy: String(meta.created_by ?? ''), + createdAt: String(meta.created_at ?? ''), + updatedAt: String(meta.updated_at ?? ''), + updatedBy: String(meta.updated_by ?? ''), + publishingStatus: Number(meta.publishing_status ?? 0), + publishingStatusDescription: String(meta.publishing_status_description ?? ''), + }; +} + +/** + * Options for setting an environment variable. + */ +export interface SetEnvVarOptions extends EnvVarOptions { + /** Environment variable name */ + key: string; + /** Environment variable value */ + value: string; +} + +/** + * Sets an environment variable on a project environment. + * + * Creates the variable if it doesn't exist, or updates it if it does. + * + * @param options - Options specifying project, environment, and variable + * @param auth - Authentication strategy (ApiKeyStrategy) + * @throws Error if request fails + * + * @example + * ```typescript + * import { ApiKeyStrategy } from '@salesforce/b2c-tooling/auth'; + * import { setEnvVar } from '@salesforce/b2c-tooling/operations/mrt'; + * + * const auth = new ApiKeyStrategy(process.env.MRT_API_KEY!, 'Authorization'); + * + * await setEnvVar({ + * projectSlug: 'my-storefront', + * environment: 'production', + * key: 'API_KEY', + * value: 'secret-value' + * }, auth); + * ``` + */ +export async function setEnvVar(options: SetEnvVarOptions, auth: AuthStrategy): Promise { + const logger = getLogger(); + const {projectSlug, environment, key, value, origin} = options; + + logger.debug({projectSlug, environment, key}, '[MRT] Setting environment variable'); + + const client = createMrtClient({origin: origin || DEFAULT_MRT_ORIGIN}, auth); + + const {error} = await client.PATCH('/api/projects/{project_slug}/target/{target_slug}/env-var/', { + params: { + path: { + project_slug: projectSlug, + target_slug: environment, + }, + }, + body: { + [key]: {value}, + }, + }); + + if (error) { + throw new Error(`Failed to set environment variable: ${JSON.stringify(error)}`); + } + + logger.debug({projectSlug, environment, key}, '[MRT] Environment variable set'); +} + +/** + * Options for setting multiple environment variables. + */ +export interface SetEnvVarsOptions extends EnvVarOptions { + /** Environment variables to set as key-value pairs */ + variables: Record; +} + +/** + * Sets multiple environment variables on a project environment. + * + * Creates variables if they don't exist, or updates them if they do. + * + * @param options - Options specifying project, environment, and variables + * @param auth - Authentication strategy (ApiKeyStrategy) + * @throws Error if request fails + * + * @example + * ```typescript + * import { ApiKeyStrategy } from '@salesforce/b2c-tooling/auth'; + * import { setEnvVars } from '@salesforce/b2c-tooling/operations/mrt'; + * + * const auth = new ApiKeyStrategy(process.env.MRT_API_KEY!, 'Authorization'); + * + * await setEnvVars({ + * projectSlug: 'my-storefront', + * environment: 'production', + * variables: { + * API_KEY: 'secret-value', + * DEBUG: 'false' + * } + * }, auth); + * ``` + */ +export async function setEnvVars(options: SetEnvVarsOptions, auth: AuthStrategy): Promise { + const logger = getLogger(); + const {projectSlug, environment, variables, origin} = options; + + const keys = Object.keys(variables); + logger.debug({projectSlug, environment, count: keys.length}, '[MRT] Setting environment variables'); + + const client = createMrtClient({origin: origin || DEFAULT_MRT_ORIGIN}, auth); + + // Build body with {key: {value}} format for each variable + const body: Record = {}; + for (const [key, value] of Object.entries(variables)) { + body[key] = {value}; + } + + const {error} = await client.PATCH('/api/projects/{project_slug}/target/{target_slug}/env-var/', { + params: { + path: { + project_slug: projectSlug, + target_slug: environment, + }, + }, + body, + }); + + if (error) { + throw new Error(`Failed to set environment variables: ${JSON.stringify(error)}`); + } + + logger.debug({projectSlug, environment, keys}, '[MRT] Environment variables set'); +} + +/** + * Options for deleting an environment variable. + */ +export interface DeleteEnvVarOptions extends EnvVarOptions { + /** Environment variable name to delete */ + key: string; +} + +/** + * Deletes an environment variable from a project environment. + * + * @param options - Options specifying project, environment, and variable name + * @param auth - Authentication strategy (ApiKeyStrategy) + * @throws Error if request fails + * + * @example + * ```typescript + * import { ApiKeyStrategy } from '@salesforce/b2c-tooling/auth'; + * import { deleteEnvVar } from '@salesforce/b2c-tooling/operations/mrt'; + * + * const auth = new ApiKeyStrategy(process.env.MRT_API_KEY!, 'Authorization'); + * + * await deleteEnvVar({ + * projectSlug: 'my-storefront', + * environment: 'production', + * key: 'OLD_API_KEY' + * }, auth); + * ``` + */ +export async function deleteEnvVar(options: DeleteEnvVarOptions, auth: AuthStrategy): Promise { + const logger = getLogger(); + const {projectSlug, environment, key, origin} = options; + + logger.debug({projectSlug, environment, key}, '[MRT] Deleting environment variable'); + + const client = createMrtClient({origin: origin || DEFAULT_MRT_ORIGIN}, auth); + + const {error} = await client.PATCH('/api/projects/{project_slug}/target/{target_slug}/env-var/', { + params: { + path: { + project_slug: projectSlug, + target_slug: environment, + }, + }, + body: { + [key]: {value: null}, + }, + }); + + if (error) { + throw new Error(`Failed to delete environment variable: ${JSON.stringify(error)}`); + } + + logger.debug({projectSlug, environment, key}, '[MRT] Environment variable deleted'); +} diff --git a/packages/b2c-tooling/src/operations/mrt/index.ts b/packages/b2c-tooling/src/operations/mrt/index.ts new file mode 100644 index 00000000..aa77729f --- /dev/null +++ b/packages/b2c-tooling/src/operations/mrt/index.ts @@ -0,0 +1,60 @@ +/** + * Managed Runtime (MRT) operations. + * + * This module provides functions for managing bundles and deployments + * on Salesforce Managed Runtime. + * + * ## Bundle Operations + * + * - {@link createBundle} - Create a bundle from a build directory + * - {@link pushBundle} - Push a bundle to MRT (creates and uploads) + * - {@link uploadBundle} - Upload a pre-created bundle + * - {@link listBundles} - List bundles for a project + * + * ## Usage + * + * ```typescript + * import { pushBundle } from '@salesforce/b2c-tooling/operations/mrt'; + * import { ApiKeyStrategy } from '@salesforce/b2c-tooling/auth'; + * + * const auth = new ApiKeyStrategy(process.env.MRT_API_KEY!, 'Authorization'); + * + * // Push and deploy a bundle + * const result = await pushBundle({ + * projectSlug: 'my-storefront', + * ssrOnly: ['ssr.js'], + * ssrShared: ['**\/*.js', 'static/**\/*'], + * buildDirectory: './build', + * message: 'Release v1.0.0', + * target: 'staging' + * }, auth); + * + * console.log(`Bundle ${result.bundleId} deployed to ${result.target}`); + * ``` + * + * ## Authentication + * + * MRT operations use API key authentication. Get your API key from the + * [Runtime Admin](https://runtime.commercecloud.com/) dashboard. + * + * @module operations/mrt + */ + +// Bundle creation +export {createBundle, createGlobFilter, getDefaultMessage, DEFAULT_SSR_PARAMETERS} from './bundle.js'; +export type {CreateBundleOptions, Bundle} from './bundle.js'; + +// Push operations +export {pushBundle, uploadBundle, listBundles} from './push.js'; +export type {PushOptions, PushResult} from './push.js'; + +// Environment variable operations +export {listEnvVars, setEnvVar, setEnvVars, deleteEnvVar} from './env-var.js'; +export type { + EnvVarOptions, + SetEnvVarOptions, + SetEnvVarsOptions, + DeleteEnvVarOptions, + ListEnvVarsResult, + EnvironmentVariable, +} from './env-var.js'; diff --git a/packages/b2c-tooling/src/operations/mrt/push.ts b/packages/b2c-tooling/src/operations/mrt/push.ts new file mode 100644 index 00000000..89b70169 --- /dev/null +++ b/packages/b2c-tooling/src/operations/mrt/push.ts @@ -0,0 +1,235 @@ +/** + * Push operations for Managed Runtime. + * + * Handles uploading bundles to MRT projects and optionally deploying them. + * + * @module operations/mrt/push + */ +import type {AuthStrategy} from '../../auth/types.js'; +import {createMrtClient, DEFAULT_MRT_ORIGIN} from '../../clients/mrt.js'; +import type {MrtClient, BuildPushResponse, components} from '../../clients/mrt.js'; +import {getLogger} from '../../logging/logger.js'; +import {createBundle} from './bundle.js'; +import type {CreateBundleOptions, Bundle} from './bundle.js'; + +/** + * Options for pushing a bundle to MRT. + */ +export interface PushOptions extends CreateBundleOptions { + /** + * Target environment to deploy to after push. + * If not provided, bundle is uploaded but not deployed. + */ + target?: string; + + /** + * MRT API origin URL. + * @default "https://cloud.mobify.com" + */ + origin?: string; +} + +/** + * Result of a push operation. + */ +export interface PushResult { + /** + * The bundle ID assigned by MRT. + */ + bundleId: number; + + /** + * The project slug the bundle was pushed to. + */ + projectSlug: string; + + /** + * The target environment if deployed. + */ + target?: string; + + /** + * Whether the bundle was deployed to the target. + */ + deployed: boolean; + + /** + * The bundle message. + */ + message: string; +} + +/** + * Pushes a bundle to a Managed Runtime project. + * + * This function creates a bundle from the build directory and uploads it + * to the specified MRT project. Optionally, it can also deploy the bundle + * to a target environment. + * + * @param options - Push configuration options + * @param auth - Authentication strategy (ApiKeyStrategy) + * @returns Result of the push operation + * @throws Error if push fails + * + * @example + * ```typescript + * import { ApiKeyStrategy } from '@salesforce/b2c-tooling/auth'; + * import { pushBundle } from '@salesforce/b2c-tooling/operations/mrt'; + * + * const auth = new ApiKeyStrategy(process.env.MRT_API_KEY!, 'Authorization'); + * + * const result = await pushBundle({ + * projectSlug: 'my-storefront', + * ssrOnly: ['ssr.js'], + * ssrShared: ['**\/*.js', 'static/**\/*'], + * buildDirectory: './build', + * message: 'Release v1.0.0', + * target: 'staging' // Optional: deploy after push + * }, auth); + * + * console.log(`Bundle ${result.bundleId} pushed to ${result.projectSlug}`); + * if (result.deployed) { + * console.log(`Deployed to ${result.target}`); + * } + * ``` + */ +export async function pushBundle(options: PushOptions, auth: AuthStrategy): Promise { + const logger = getLogger(); + const {projectSlug, target, origin} = options; + + logger.debug({projectSlug, target}, '[MRT] Pushing bundle'); + + // Create the bundle + const bundle = await createBundle(options); + + // Create MRT client + const client = createMrtClient({origin: origin || DEFAULT_MRT_ORIGIN}, auth); + + // Upload the bundle + const result = await uploadBundle(client, projectSlug, bundle, target); + + logger.debug({bundleId: result.bundleId, deployed: result.deployed}, '[MRT] Bundle pushed successfully'); + + return result; +} + +/** + * Uploads a pre-created bundle to MRT. + * + * Use this if you've already created a bundle and want to upload it separately. + * + * @param client - MRT client instance + * @param projectSlug - Project to upload to + * @param bundle - Bundle to upload + * @param target - Optional target to deploy to + * @returns Result of the upload + */ +export async function uploadBundle( + client: MrtClient, + projectSlug: string, + bundle: Bundle, + target?: string, +): Promise { + const logger = getLogger(); + + // Choose endpoint based on whether we're deploying + if (target) { + logger.debug({projectSlug, target}, '[MRT] Uploading and deploying bundle'); + + const {data, error} = await client.POST('/api/projects/{project_slug}/builds/{target_slug}/', { + params: { + path: { + project_slug: projectSlug, + target_slug: target, + }, + }, + body: { + message: bundle.message, + encoding: bundle.encoding, + data: bundle.data, + ssr_parameters: bundle.ssr_parameters, + ssr_only: bundle.ssr_only, + ssr_shared: bundle.ssr_shared, + }, + }); + + if (error) { + throw new Error(`Failed to push bundle: ${JSON.stringify(error)}`); + } + + const buildData = data as unknown as BuildPushResponse; + + return { + bundleId: buildData.bundle_id, + projectSlug, + target, + deployed: true, + message: bundle.message, + }; + } else { + logger.debug({projectSlug}, '[MRT] Uploading bundle (no deployment)'); + + const {data, error} = await client.POST('/api/projects/{project_slug}/builds/', { + params: { + path: { + project_slug: projectSlug, + }, + }, + body: { + message: bundle.message, + encoding: bundle.encoding, + data: bundle.data, + ssr_parameters: bundle.ssr_parameters, + ssr_only: bundle.ssr_only, + ssr_shared: bundle.ssr_shared, + }, + }); + + if (error) { + throw new Error(`Failed to push bundle: ${JSON.stringify(error)}`); + } + + const buildData = data as unknown as BuildPushResponse; + + return { + bundleId: buildData.bundle_id, + projectSlug, + deployed: false, + message: bundle.message, + }; + } +} + +/** + * Gets the list of bundles for a project. + * + * @param client - MRT client instance + * @param projectSlug - Project to list bundles for + * @param options - Pagination options + * @returns List of bundles + */ +export async function listBundles( + client: MrtClient, + projectSlug: string, + options?: {limit?: number; offset?: number}, +): Promise { + const logger = getLogger(); + + logger.debug({projectSlug}, '[MRT] Listing bundles'); + + const {data, error} = await client.GET('/api/projects/{project_slug}/bundles/', { + params: { + path: {project_slug: projectSlug}, + query: { + limit: options?.limit, + offset: options?.offset, + }, + }, + }); + + if (error) { + throw new Error(`Failed to list bundles: ${JSON.stringify(error)}`); + } + + return data?.results || []; +} diff --git a/packages/b2c-tooling/src/platform/index.ts b/packages/b2c-tooling/src/platform/index.ts index 1cc57525..44a67343 100644 --- a/packages/b2c-tooling/src/platform/index.ts +++ b/packages/b2c-tooling/src/platform/index.ts @@ -6,7 +6,7 @@ * * ## Available Clients * - * - {@link MrtClient} - Managed Runtime (MRT) API for PWA Kit deployments + * - {@link MrtClient} - Managed Runtime (MRT) API for deployments * - {@link OdsClient} - On-Demand Sandbox API for sandbox management * * ## Usage diff --git a/packages/b2c-tooling/src/types/cliui.d.ts b/packages/b2c-tooling/src/types/cliui.d.ts new file mode 100644 index 00000000..7ff73fcd --- /dev/null +++ b/packages/b2c-tooling/src/types/cliui.d.ts @@ -0,0 +1,24 @@ +declare module 'cliui' { + interface Column { + text: string; + width?: number; + align?: 'center' | 'left' | 'right'; + padding?: [number, number, number, number]; + border?: boolean; + } + + interface UIOptions { + width?: number; + wrap?: boolean; + } + + interface UI { + div(...columns: (Column | string)[]): void; + span(...columns: (Column | string)[]): void; + resetOutput(): void; + toString(): string; + } + + function cliui(options?: UIOptions): UI; + export default cliui; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8ac89c6..44c7e3dc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -105,9 +105,15 @@ importers: packages/b2c-tooling: dependencies: + archiver: + specifier: ^7.0.1 + version: 7.0.1 chokidar: specifier: ^5.0.0 version: 5.0.0 + cliui: + specifier: ^9.0.1 + version: 9.0.1 glob: specifier: ^13.0.0 version: 13.0.0 @@ -117,6 +123,9 @@ importers: jszip: specifier: ^3.10.1 version: 3.10.1 + minimatch: + specifier: ^10.1.1 + version: 10.1.1 open: specifier: ^11.0.0 version: 11.0.0 @@ -142,6 +151,9 @@ importers: '@salesforce/dev-config': specifier: ^4.3.2 version: 4.3.2 + '@types/archiver': + specifier: ^7.0.0 + version: 7.0.0 '@types/node': specifier: ^18.19.130 version: 18.19.130 @@ -1028,6 +1040,10 @@ packages: resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} @@ -1090,6 +1106,10 @@ packages: '@pinojs/redact@0.4.0': resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@pkgr/core@0.2.9': resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -1518,6 +1538,9 @@ packages: '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/archiver@7.0.0': + resolution: {integrity: sha512-/3vwGwx9n+mCQdYZ2IKGGHEFL30I96UgBlk8EtRDDFQ9uxM1l4O5Ci6r00EMAkiDaTqD9DQ6nVrWRICnBPtzzg==} + '@types/chai@4.3.20': resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} @@ -1563,6 +1586,9 @@ packages: '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/readdir-glob@1.1.5': + resolution: {integrity: sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -1832,6 +1858,10 @@ packages: '@vueuse/shared@12.8.2': resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==} + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1885,6 +1915,14 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + archiver-utils@5.0.2: + resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} + engines: {node: '>= 14'} + + archiver@7.0.1: + resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} + engines: {node: '>= 14'} + are-docs-informative@0.0.2: resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} engines: {node: '>=14'} @@ -1937,9 +1975,28 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + b4a@1.7.3: + resolution: {integrity: sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + bare-events@2.8.2: + resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} + peerDependencies: + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.8.26: resolution: {integrity: sha512-73lC1ugzwoaWCLJ1LvOgrR5xsMLTqSKIEoMHVtL9E/HNk0PXtTM76ZIm84856/SF7Nv8mPZxKoBsgpm0tR1u1Q==} hasBin: true @@ -1972,6 +2029,13 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} @@ -2108,6 +2172,10 @@ packages: resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} engines: {node: '>= 12.0.0'} + compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -2134,6 +2202,15 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@6.0.0: + resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} + engines: {node: '>= 14'} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -2242,6 +2319,9 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + ejs@3.1.10: resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} engines: {node: '>=0.10.0'} @@ -2259,6 +2339,9 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} @@ -2539,6 +2622,17 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + events-universal@1.0.1: + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + fast-copy@3.0.2: resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==} @@ -2548,6 +2642,9 @@ packages: fast-diff@1.3.0: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -2627,6 +2724,10 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + form-data-encoder@2.1.4: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} engines: {node: '>= 14.17'} @@ -2709,6 +2810,10 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + hasBin: true + glob@13.0.0: resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==} engines: {node: 20 || >=22} @@ -2845,6 +2950,9 @@ packages: resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} engines: {node: '>=0.10.0'} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -3072,6 +3180,9 @@ packages: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jake@10.9.4: resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} engines: {node: '>=10'} @@ -3136,6 +3247,10 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -3504,6 +3619,9 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -3557,6 +3675,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.1: resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} engines: {node: 20 || >=22} @@ -3634,6 +3756,10 @@ packages: process-warning@5.0.0: resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} @@ -3678,6 +3804,13 @@ packages: readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -3933,10 +4066,17 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + streamx@2.23.0: + resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + string-width@7.2.0: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} @@ -3956,6 +4096,9 @@ packages: string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} @@ -4017,6 +4160,12 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + + text-decoder@1.2.3: + resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + thread-stream@3.1.0: resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} @@ -4298,6 +4447,10 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrap-ansi@9.0.2: resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} engines: {node: '>=18'} @@ -4350,6 +4503,10 @@ packages: resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} engines: {node: '>=18'} + zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -5479,6 +5636,15 @@ snapshots: dependencies: '@isaacs/balanced-match': 4.0.1 + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/sourcemap-codec@1.5.5': {} '@napi-rs/wasm-runtime@0.2.12': @@ -5589,6 +5755,9 @@ snapshots: '@pinojs/redact@0.4.0': {} + '@pkgjs/parseargs@0.11.0': + optional: true + '@pkgr/core@0.2.9': {} '@pnpm/config.env-replace@1.1.0': {} @@ -6125,6 +6294,10 @@ snapshots: tslib: 2.8.1 optional: true + '@types/archiver@7.0.0': + dependencies: + '@types/readdir-glob': 1.1.5 + '@types/chai@4.3.20': {} '@types/estree@1.0.8': {} @@ -6168,6 +6341,10 @@ snapshots: '@types/normalize-package-data@2.4.4': {} + '@types/readdir-glob@1.1.5': + dependencies: + '@types/node': 18.19.130 + '@types/unist@3.0.3': {} '@types/web-bluetooth@0.0.21': {} @@ -6433,6 +6610,10 @@ snapshots: transitivePeerDependencies: - typescript + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -6488,6 +6669,29 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + archiver-utils@5.0.2: + dependencies: + glob: 10.5.0 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.17.21 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + archiver@7.0.1: + dependencies: + archiver-utils: 5.0.2 + async: 3.2.6 + buffer-crc32: 1.0.0 + readable-stream: 4.7.0 + readdir-glob: 1.1.3 + tar-stream: 3.1.7 + zip-stream: 6.0.1 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + are-docs-informative@0.0.2: {} argparse@2.0.1: {} @@ -6558,8 +6762,14 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + b4a@1.7.3: {} + balanced-match@1.0.2: {} + bare-events@2.8.2: {} + + base64-js@1.5.1: {} + baseline-browser-mapping@2.8.26: {} binary-extensions@2.3.0: {} @@ -6591,6 +6801,13 @@ snapshots: node-releases: 2.0.27 update-browserslist-db: 1.1.4(browserslist@4.28.0) + buffer-crc32@1.0.0: {} + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + builtin-modules@3.3.0: {} builtins@5.1.0: @@ -6749,6 +6966,14 @@ snapshots: comment-parser@1.4.1: {} + compress-commons@6.0.2: + dependencies: + crc-32: 1.2.2 + crc32-stream: 6.0.0 + is-stream: 2.0.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + concat-map@0.0.1: {} config-chain@1.1.13: @@ -6776,6 +7001,13 @@ snapshots: core-util-is@1.0.3: {} + crc-32@1.2.2: {} + + crc32-stream@6.0.0: + dependencies: + crc-32: 1.2.2 + readable-stream: 4.7.0 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -6882,6 +7114,8 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + eastasianwidth@0.2.0: {} + ejs@3.1.10: dependencies: jake: 10.9.4 @@ -6894,6 +7128,8 @@ snapshots: emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} + end-of-stream@1.4.5: dependencies: once: 1.4.0 @@ -7380,12 +7616,24 @@ snapshots: esutils@2.0.3: {} + event-target-shim@5.0.1: {} + + events-universal@1.0.1: + dependencies: + bare-events: 2.8.2 + transitivePeerDependencies: + - bare-abort-controller + + events@3.3.0: {} + fast-copy@3.0.2: {} fast-deep-equal@3.1.3: {} fast-diff@1.3.0: {} + fast-fifo@1.3.2: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -7463,6 +7711,11 @@ snapshots: dependencies: is-callable: 1.2.7 + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + form-data-encoder@2.1.4: {} fs-extra@8.1.0: @@ -7543,6 +7796,15 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + glob@13.0.0: dependencies: minimatch: 10.1.1 @@ -7699,6 +7961,8 @@ snapshots: dependencies: safer-buffer: 2.1.2 + ieee754@1.2.1: {} + ignore@5.3.2: {} ignore@7.0.5: {} @@ -7895,6 +8159,12 @@ snapshots: isexe@3.1.1: {} + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jake@10.9.4: dependencies: async: 3.2.6 @@ -7948,6 +8218,10 @@ snapshots: dependencies: json-buffer: 3.0.1 + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -8297,6 +8571,8 @@ snapshots: p-try@2.2.0: {} + package-json-from-dist@1.0.1: {} + pako@1.0.11: {} param-case@3.0.4: @@ -8352,6 +8628,11 @@ snapshots: path-parse@1.0.7: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + path-scurry@2.0.1: dependencies: lru-cache: 11.2.2 @@ -8431,6 +8712,8 @@ snapshots: process-warning@5.0.0: {} + process@0.11.10: {} + property-information@7.1.0: {} proto-list@1.2.4: {} @@ -8479,6 +8762,18 @@ snapshots: string_decoder: 1.1.1 util-deprecate: 1.0.2 + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.6 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 @@ -8778,12 +9073,27 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 + streamx@2.23.0: + dependencies: + events-universal: 1.0.1 + fast-fifo: 1.3.2 + text-decoder: 1.2.3 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 + string-width@7.2.0: dependencies: emoji-regex: 10.6.0 @@ -8817,6 +9127,10 @@ snapshots: dependencies: safe-buffer: 5.1.2 + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + stringify-entities@4.0.4: dependencies: character-entities-html4: 2.1.0 @@ -8866,6 +9180,21 @@ snapshots: tapable@2.3.0: {} + tar-stream@3.1.7: + dependencies: + b4a: 1.7.3 + fast-fifo: 1.3.2 + streamx: 2.23.0 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + text-decoder@1.2.3: + dependencies: + b4a: 1.7.3 + transitivePeerDependencies: + - react-native-b4a + thread-stream@3.1.0: dependencies: real-require: 0.2.0 @@ -9229,6 +9558,12 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + wrap-ansi@9.0.2: dependencies: ansi-styles: 6.2.3 @@ -9275,4 +9610,10 @@ snapshots: yoctocolors-cjs@2.1.3: {} + zip-stream@6.0.1: + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.7.0 + zwitch@2.0.4: {} diff --git a/typedoc.json b/typedoc.json index a8489f91..c84c3c67 100644 --- a/typedoc.json +++ b/typedoc.json @@ -2,14 +2,17 @@ "$schema": "https://typedoc.org/schema.json", "entryPoints": [ "./packages/b2c-tooling/src/auth/index.ts", + "./packages/b2c-tooling/src/cli/index.ts", "./packages/b2c-tooling/src/clients/index.ts", + "./packages/b2c-tooling/src/config/index.ts", + "./packages/b2c-tooling/src/i18n/index.ts", "./packages/b2c-tooling/src/instance/index.ts", - "./packages/b2c-tooling/src/platform/index.ts", + "./packages/b2c-tooling/src/logging/index.ts", "./packages/b2c-tooling/src/operations/code/index.ts", "./packages/b2c-tooling/src/operations/jobs/index.ts", + "./packages/b2c-tooling/src/operations/mrt/index.ts", "./packages/b2c-tooling/src/operations/sites/index.ts", - "./packages/b2c-tooling/src/i18n/index.ts", - "./packages/b2c-tooling/src/logging/index.ts" + "./packages/b2c-tooling/src/platform/index.ts" ], "exclude": ["**/*.generated.ts"], "out": "./docs/api",