Files
memind/scripts/generate-openapi.mjs
John 2e14873f2d Initial commit: Memind H5 portal with MindSpace, Plaza, and agent jobs.
Track application source and tests; exclude local env, user workspaces, and runtime data via .gitignore.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:04:43 -07:00

976 lines
30 KiB
JavaScript

#!/usr/bin/env node
import fs from 'node:fs/promises';
import path from 'node:path';
import { plazaOpenApiExtensions } from './plaza-openapi.mjs';
const OUTPUT_PATH = path.join(import.meta.dirname, '..', 'openapi.json');
const plazaOpenApi = plazaOpenApiExtensions();
const jsonContent = {
openapi: '3.0.3',
info: {
title: 'MindSpace H5 API',
version: '0.1.0',
description: 'Generated OpenAPI contract for MindSpace H5, Plaza, and public publication routes.',
},
servers: [
{ url: '/api', description: 'Authenticated H5 API' },
{ url: '/', description: 'Public publication and homepage routes' },
],
tags: [
{ name: 'Auth' },
{ name: 'Space' },
{ name: 'Uploads' },
{ name: 'Assets' },
{ name: 'Pages' },
{ name: 'Publications' },
{ name: 'Agent Jobs' },
{ name: 'Public Web' },
...plazaOpenApi.tags,
],
paths: {
'/auth/register': {
post: {
tags: ['Auth'],
summary: 'Register a user and initialize a MindSpace workspace',
requestBody: {
required: true,
content: {
'application/json': {
schema: { $ref: '#/components/schemas/RegisterRequest' },
},
},
},
responses: {
200: {
description: 'Registration succeeded',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/RegisterResponseEnvelope' },
},
},
},
},
},
},
'/auth/login': {
post: {
tags: ['Auth'],
summary: 'Login with username and password',
requestBody: {
required: true,
content: {
'application/json': {
schema: { $ref: '#/components/schemas/LoginRequest' },
},
},
},
responses: {
200: {
description: 'Authenticated session',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/AuthStatus' },
},
},
},
},
},
},
'/auth/logout': {
post: {
tags: ['Auth'],
summary: 'Logout current user session',
responses: {
200: {
description: 'Logged out',
content: { 'application/json': { schema: { $ref: '#/components/schemas/SuccessEnvelope' } } },
},
},
},
},
'/auth/status': {
get: {
tags: ['Auth'],
summary: 'Inspect current auth/session status',
responses: {
200: {
description: 'Current auth status',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/AuthStatus' },
},
},
},
},
},
},
'/mindspace/v1/space': {
get: {
tags: ['Space'],
summary: 'Get current MindSpace summary, quota, and categories',
responses: {
200: {
description: 'Current space',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/DataEnvelope' },
},
},
},
},
},
},
'/mindspace/v1/space/quota': {
get: {
tags: ['Space'],
summary: 'Get current quota state',
responses: {
200: {
description: 'Quota state',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/space/categories': {
get: {
tags: ['Space'],
summary: 'List current space categories',
responses: {
200: {
description: 'Category list',
content: { 'application/json': { schema: { $ref: '#/components/schemas/ListEnvelope' } } },
},
},
},
},
'/mindspace/v1/space/cleanup': {
get: {
tags: ['Space'],
summary: 'Preview cleanup candidates',
responses: {
200: {
description: 'Cleanup candidates',
content: { 'application/json': { schema: { $ref: '#/components/schemas/ListEnvelope' } } },
},
},
},
post: {
tags: ['Space'],
summary: 'Delete selected cleanup candidates',
requestBody: {
required: true,
content: {
'application/json': {
schema: { $ref: '#/components/schemas/CleanupRequest' },
},
},
},
responses: {
200: {
description: 'Cleanup result',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/uploads': {
post: {
tags: ['Uploads'],
summary: 'Create an upload session',
requestBody: {
required: true,
content: {
'application/json': {
schema: { $ref: '#/components/schemas/CreateUploadRequest' },
},
},
},
responses: {
201: {
description: 'Upload session created',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/uploads/{uploadId}/content': {
put: {
tags: ['Uploads'],
summary: 'Upload raw file bytes',
parameters: [{ $ref: '#/components/parameters/UploadId' }],
requestBody: {
required: true,
content: {
'application/octet-stream': {
schema: { type: 'string', format: 'binary' },
},
},
},
responses: {
200: {
description: 'Bytes written',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/uploads/{uploadId}/complete': {
post: {
tags: ['Uploads'],
summary: 'Complete an upload and materialize the asset',
parameters: [{ $ref: '#/components/parameters/UploadId' }],
responses: {
201: {
description: 'Asset created',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/uploads/{uploadId}': {
delete: {
tags: ['Uploads'],
summary: 'Cancel upload session',
parameters: [{ $ref: '#/components/parameters/UploadId' }],
responses: {
200: {
description: 'Upload cancelled',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/assets': {
get: {
tags: ['Assets'],
summary: 'List assets',
parameters: [
{ name: 'category_id', in: 'query', schema: { type: 'string' } },
{ name: 'category_code', in: 'query', schema: { type: 'string' } },
],
responses: {
200: {
description: 'Asset list',
content: { 'application/json': { schema: { $ref: '#/components/schemas/ListEnvelope' } } },
},
},
},
},
'/mindspace/v1/assets/{assetId}/download': {
get: {
tags: ['Assets'],
summary: 'Download asset bytes',
parameters: [{ $ref: '#/components/parameters/AssetId' }],
responses: {
200: {
description: 'Asset content',
content: { '*/*': { schema: { type: 'string', format: 'binary' } } },
},
},
},
},
'/mindspace/v1/assets/{assetId}/thumbnail': {
get: {
tags: ['Assets'],
summary: 'Render asset thumbnail',
parameters: [{ $ref: '#/components/parameters/AssetId' }],
responses: {
200: {
description: 'SVG thumbnail',
content: { 'image/svg+xml': { schema: { type: 'string' } } },
},
},
},
},
'/mindspace/v1/assets/{assetId}/preview': {
get: {
tags: ['Assets'],
summary: 'Render asset preview HTML',
parameters: [{ $ref: '#/components/parameters/AssetId' }],
responses: {
200: {
description: 'Preview HTML',
content: { 'text/html': { schema: { type: 'string' } } },
},
},
},
},
'/mindspace/v1/assets/{assetId}': {
delete: {
tags: ['Assets'],
summary: 'Delete asset',
parameters: [{ $ref: '#/components/parameters/AssetId' }],
responses: {
200: {
description: 'Delete result',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/pages/analyze-chat-save': {
post: {
tags: ['Pages'],
summary: 'Analyze whether an assistant message should be saved as page or asset',
requestBody: {
required: true,
content: { 'application/json': { schema: { $ref: '#/components/schemas/AnalyzeChatSaveRequest' } } },
},
responses: {
200: {
description: 'Chat save analysis',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/pages/save-from-chat': {
post: {
tags: ['Pages'],
summary: 'Save assistant message into MindSpace',
requestBody: {
required: true,
content: { 'application/json': { schema: { $ref: '#/components/schemas/SaveFromChatRequest' } } },
},
responses: {
201: {
description: 'Saved page or asset',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/pages/from-asset': {
post: {
tags: ['Pages'],
summary: 'Convert an owned asset into a draft page',
requestBody: {
required: true,
content: { 'application/json': { schema: { $ref: '#/components/schemas/PageFromAssetRequest' } } },
},
responses: {
201: {
description: 'Draft page created',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/pages': {
get: {
tags: ['Pages'],
summary: 'List pages',
parameters: [{ name: 'status', in: 'query', schema: { type: 'string' } }],
responses: {
200: {
description: 'Page list',
content: { 'application/json': { schema: { $ref: '#/components/schemas/ListEnvelope' } } },
},
},
},
post: {
tags: ['Pages'],
summary: 'Create a draft page',
requestBody: {
required: true,
content: { 'application/json': { schema: { $ref: '#/components/schemas/CreatePageRequest' } } },
},
responses: {
201: {
description: 'Page created',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/pages/{pageId}': {
get: {
tags: ['Pages'],
summary: 'Get page detail and versions',
parameters: [{ $ref: '#/components/parameters/PageId' }],
responses: {
200: {
description: 'Page detail',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
put: {
tags: ['Pages'],
summary: 'Create a new page version',
parameters: [{ $ref: '#/components/parameters/PageId' }],
requestBody: {
required: true,
content: { 'application/json': { schema: { $ref: '#/components/schemas/UpdatePageRequest' } } },
},
responses: {
200: {
description: 'Updated page',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/pages/{pageId}/thumbnail': {
get: {
tags: ['Pages'],
summary: 'Render page thumbnail',
parameters: [{ $ref: '#/components/parameters/PageId' }],
responses: {
200: {
description: 'SVG thumbnail',
content: { 'image/svg+xml': { schema: { type: 'string' } } },
},
},
},
},
'/mindspace/v1/pages/{pageId}/preview': {
get: {
tags: ['Pages'],
summary: 'Render safe page preview HTML',
parameters: [{ $ref: '#/components/parameters/PageId' }],
responses: {
200: {
description: 'Preview HTML',
content: { 'text/html': { schema: { type: 'string' } } },
},
},
},
},
'/mindspace/v1/pages/{pageId}/publish-check': {
post: {
tags: ['Publications'],
summary: 'Check whether page can be published',
parameters: [{ $ref: '#/components/parameters/PageId' }],
requestBody: {
required: true,
content: { 'application/json': { schema: { $ref: '#/components/schemas/PublishCheckRequest' } } },
},
responses: {
200: {
description: 'Publish check result',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/pages/{pageId}/redacted-copy': {
post: {
tags: ['Pages'],
summary: 'Create a redacted copy of the current page version',
parameters: [{ $ref: '#/components/parameters/PageId' }],
requestBody: {
required: true,
content: { 'application/json': { schema: { $ref: '#/components/schemas/RedactedCopyRequest' } } },
},
responses: {
201: {
description: 'Redacted page created',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/pages/{pageId}/publish': {
post: {
tags: ['Publications'],
summary: 'Publish the current page version',
parameters: [{ $ref: '#/components/parameters/PageId' }],
requestBody: {
required: true,
content: { 'application/json': { schema: { $ref: '#/components/schemas/PublishPageRequest' } } },
},
responses: {
201: {
description: 'Publication created',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/publications/{publicationId}/offline': {
post: {
tags: ['Publications'],
summary: 'Offline an online publication',
parameters: [{ $ref: '#/components/parameters/PublicationId' }],
responses: {
200: {
description: 'Publication offlined',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/publications/{publicationId}/stats': {
get: {
tags: ['Publications'],
summary: 'Get publication statistics',
parameters: [{ $ref: '#/components/parameters/PublicationId' }],
responses: {
200: {
description: 'Publication stats',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/agent/jobs': {
get: {
tags: ['Agent Jobs'],
summary: 'List current user agent jobs',
parameters: [{ name: 'limit', in: 'query', schema: { type: 'integer' } }],
responses: {
200: {
description: 'Job list',
content: { 'application/json': { schema: { $ref: '#/components/schemas/ListEnvelope' } } },
},
},
},
post: {
tags: ['Agent Jobs'],
summary: 'Create an agent job bound to owned assets',
requestBody: {
required: true,
content: { 'application/json': { schema: { $ref: '#/components/schemas/CreateAgentJobRequest' } } },
},
responses: {
201: {
description: 'Job created',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/agent/jobs/{jobId}': {
get: {
tags: ['Agent Jobs'],
summary: 'Get agent job detail',
parameters: [{ $ref: '#/components/parameters/JobId' }],
responses: {
200: {
description: 'Job detail',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/agent/jobs/{jobId}/cancel': {
post: {
tags: ['Agent Jobs'],
summary: 'Cancel agent job',
parameters: [{ $ref: '#/components/parameters/JobId' }],
responses: {
200: {
description: 'Cancelled job',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/agent/jobs/{jobId}/retry': {
post: {
tags: ['Agent Jobs'],
summary: 'Retry agent job',
parameters: [{ $ref: '#/components/parameters/JobId' }],
responses: {
200: {
description: 'Retried job',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/mindspace/v1/agent/jobs/{jobId}/run': {
post: {
tags: ['Agent Jobs'],
summary: 'Start queued agent job execution',
parameters: [{ $ref: '#/components/parameters/JobId' }],
responses: {
202: {
description: 'Execution started',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/internal/agent/jobs/{jobId}/claim': {
post: {
tags: ['Agent Jobs'],
summary: 'Internal worker claims a queued job',
parameters: [{ $ref: '#/components/parameters/JobId' }],
security: [{ bearerAuth: [] }],
responses: {
200: {
description: 'Claimed job payload',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/internal/agent/jobs/{jobId}/assets/{assetId}': {
get: {
tags: ['Agent Jobs'],
summary: 'Internal worker downloads an authorized job asset',
parameters: [{ $ref: '#/components/parameters/JobId' }, { $ref: '#/components/parameters/AssetId' }],
security: [{ bearerAuth: [] }],
responses: {
200: {
description: 'Asset content',
content: { '*/*': { schema: { type: 'string', format: 'binary' } } },
},
},
},
},
'/internal/agent/jobs/{jobId}/heartbeat': {
post: {
tags: ['Agent Jobs'],
summary: 'Internal worker posts heartbeat/progress updates',
parameters: [{ $ref: '#/components/parameters/JobId' }],
security: [{ bearerAuth: [] }],
requestBody: {
required: true,
content: { 'application/json': { schema: { $ref: '#/components/schemas/HeartbeatRequest' } } },
},
responses: {
200: {
description: 'Progress updated',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/internal/agent/jobs/{jobId}/complete': {
post: {
tags: ['Agent Jobs'],
summary: 'Internal worker completes or fails a job',
parameters: [{ $ref: '#/components/parameters/JobId' }],
security: [{ bearerAuth: [] }],
requestBody: {
required: true,
content: { 'application/json': { schema: { $ref: '#/components/schemas/CompleteJobRequest' } } },
},
responses: {
200: {
description: 'Final job state',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
},
},
},
},
'/u/{ownerSlug}': {
get: {
tags: ['Public Web'],
summary: 'Render public homepage for a user slug',
parameters: [{ $ref: '#/components/parameters/OwnerSlug' }],
responses: {
200: {
description: 'Public homepage HTML',
content: { 'text/html': { schema: { type: 'string' } } },
},
},
},
},
'/u/{ownerSlug}/pages/{urlSlug}': {
get: {
tags: ['Public Web'],
summary: 'Render a published page via long public route',
parameters: [{ $ref: '#/components/parameters/OwnerSlug' }, { $ref: '#/components/parameters/UrlSlug' }],
responses: {
200: {
description: 'Published page HTML',
content: { 'text/html': { schema: { type: 'string' } } },
},
},
},
post: {
tags: ['Public Web'],
summary: 'Submit password gate for a protected page',
parameters: [{ $ref: '#/components/parameters/OwnerSlug' }, { $ref: '#/components/parameters/UrlSlug' }],
requestBody: {
required: true,
content: {
'application/x-www-form-urlencoded': {
schema: {
type: 'object',
required: ['password'],
properties: { password: { type: 'string' } },
},
},
},
},
responses: {
200: {
description: 'Published page HTML or password gate',
content: { 'text/html': { schema: { type: 'string' } } },
},
},
},
},
'/s/{token}': {
get: {
tags: ['Public Web'],
summary: 'Render a private-link publication',
parameters: [{ name: 'token', in: 'path', required: true, schema: { type: 'string' } }],
responses: {
200: {
description: 'Published page HTML',
content: { 'text/html': { schema: { type: 'string' } } },
},
},
},
},
...plazaOpenApi.paths,
},
components: {
securitySchemes: {
bearerAuth: {
type: 'http',
scheme: 'bearer',
},
},
parameters: {
UploadId: { name: 'uploadId', in: 'path', required: true, schema: { type: 'string' } },
AssetId: { name: 'assetId', in: 'path', required: true, schema: { type: 'string' } },
PageId: { name: 'pageId', in: 'path', required: true, schema: { type: 'string' } },
PublicationId: { name: 'publicationId', in: 'path', required: true, schema: { type: 'string' } },
JobId: { name: 'jobId', in: 'path', required: true, schema: { type: 'string' } },
OwnerSlug: { name: 'ownerSlug', in: 'path', required: true, schema: { type: 'string' } },
UrlSlug: { name: 'urlSlug', in: 'path', required: true, schema: { type: 'string' } },
...plazaOpenApi.parameters,
},
schemas: {
SuccessEnvelope: {
type: 'object',
properties: {
ok: { type: 'boolean' },
request_id: { type: 'string' },
},
},
DataEnvelope: {
type: 'object',
required: ['data', 'request_id'],
properties: {
data: { type: 'object', additionalProperties: true },
request_id: { type: 'string' },
},
},
ListEnvelope: {
type: 'object',
required: ['data', 'request_id'],
properties: {
data: { type: 'array', items: { type: 'object', additionalProperties: true } },
page: {
type: 'object',
properties: {
next_cursor: { type: ['string', 'null'] },
has_more: { type: 'boolean' },
},
},
request_id: { type: 'string' },
},
},
AuthStatus: {
type: 'object',
additionalProperties: true,
},
RegisterRequest: {
type: 'object',
required: ['username', 'password', 'displayName', 'email'],
properties: {
username: { type: 'string' },
password: { type: 'string' },
displayName: { type: 'string' },
email: { type: 'string' },
},
},
RegisterResponseEnvelope: {
type: 'object',
properties: {
ok: { type: 'boolean' },
user: { type: 'object', additionalProperties: true },
},
},
LoginRequest: {
type: 'object',
required: ['username', 'password'],
properties: {
username: { type: 'string' },
password: { type: 'string' },
},
},
CleanupRequest: {
type: 'object',
properties: {
item_ids: { type: 'array', items: { type: 'string' } },
},
},
CreateUploadRequest: {
type: 'object',
required: ['category_id', 'filename', 'size_bytes'],
properties: {
category_id: { type: 'string' },
filename: { type: 'string' },
size_bytes: { type: 'integer' },
declared_mime_type: { type: 'string' },
},
},
AnalyzeChatSaveRequest: {
type: 'object',
required: ['session_id', 'message_id'],
properties: {
session_id: { type: 'string' },
message_id: { type: 'string' },
selected_link_index: { type: 'integer' },
},
},
SaveFromChatRequest: {
type: 'object',
required: ['session_id', 'message_id'],
properties: {
session_id: { type: 'string' },
message_id: { type: 'string' },
title: { type: 'string' },
summary: { type: 'string' },
template_id: { type: 'string' },
category_code: { type: 'string' },
page_type: { type: 'string' },
selected_link_index: { type: 'integer' },
acknowledged_finding_ids: { type: 'array', items: { type: 'string' } },
},
},
PageFromAssetRequest: {
type: 'object',
required: ['asset_id'],
properties: {
asset_id: { type: 'string' },
title: { type: 'string' },
summary: { type: 'string' },
template_id: { type: 'string' },
},
},
CreatePageRequest: {
type: 'object',
required: ['title', 'content'],
properties: {
title: { type: 'string' },
summary: { type: 'string' },
content: { type: 'string' },
content_format: { type: 'string', enum: ['markdown', 'html'] },
template_id: { type: 'string' },
page_type: { type: 'string' },
category_code: { type: 'string' },
},
},
UpdatePageRequest: {
type: 'object',
required: ['expected_version', 'title', 'content'],
properties: {
expected_version: { type: 'integer' },
title: { type: 'string' },
summary: { type: 'string' },
content: { type: 'string' },
template_id: { type: 'string' },
page_type: { type: 'string' },
change_note: { type: 'string' },
},
},
PublishCheckRequest: {
type: 'object',
required: ['page_version_id', 'access_mode', 'url_slug'],
properties: {
page_version_id: { type: 'string' },
access_mode: { type: 'string' },
url_slug: { type: 'string' },
password: { type: 'string' },
expires_at: { type: 'integer' },
},
},
RedactedCopyRequest: {
type: 'object',
properties: {
page_version_id: { type: 'string' },
},
},
PublishPageRequest: {
type: 'object',
required: ['page_version_id', 'access_mode', 'url_slug'],
properties: {
page_version_id: { type: 'string' },
access_mode: { type: 'string' },
url_slug: { type: 'string' },
password: { type: 'string' },
expires_at: { type: 'integer' },
acknowledged_finding_ids: { type: 'array', items: { type: 'string' } },
},
},
CreateAgentJobRequest: {
type: 'object',
required: ['job_type', 'instruction', 'allowed_asset_ids'],
properties: {
job_type: { type: 'string' },
instruction: { type: 'string' },
allowed_asset_ids: { type: 'array', items: { type: 'string' } },
output_category_id: { type: 'string' },
output_type: { type: 'string' },
idempotency_key: { type: 'string' },
locale: { type: 'string' },
timezone: { type: 'string' },
capabilities: { type: 'object', additionalProperties: { type: 'boolean' } },
},
},
HeartbeatRequest: {
type: 'object',
properties: {
stage: { type: 'string' },
message: { type: 'string' },
},
},
CompleteJobRequest: {
type: 'object',
properties: {
status: { type: 'string' },
error_code: { type: 'string' },
error_message: { type: 'string' },
output_type: { type: 'string' },
title: { type: 'string' },
summary: { type: 'string' },
content: { type: 'string' },
content_format: { type: 'string' },
page_type: { type: 'string' },
template_id: { type: 'string' },
source_asset_ids: { type: 'array', items: { type: 'string' } },
},
},
ErrorResponse: {
type: 'object',
properties: {
error: {
type: 'object',
properties: {
code: { type: 'string' },
message: { type: 'string' },
details: { type: 'object', additionalProperties: true },
},
},
request_id: { type: 'string' },
},
},
...plazaOpenApi.schemas,
},
},
};
async function main() {
const rendered = `${JSON.stringify(jsonContent, null, 2)}\n`;
if (process.argv.includes('--print')) {
process.stdout.write(rendered);
return;
}
await fs.writeFile(OUTPUT_PATH, rendered);
process.stdout.write(`Generated ${OUTPUT_PATH}\n`);
}
await main();