create-nextblock 0.16.4 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +22 -0
- package/docker-template/.env.docker.example +69 -69
- package/docker-template/docker/db/init/99-jwt.sql +6 -6
- package/docker-template/docker/db/init/99-roles.sql +25 -25
- package/docker-template/docker/kong/kong.yml +112 -112
- package/docker-template/scripts/docker-setup.mjs +310 -310
- package/package.json +1 -1
- package/templates/nextblock-template/.browserslistrc +11 -11
- package/templates/nextblock-template/.swcrc +30 -30
- package/templates/nextblock-template/CLAUDE.md +26 -0
- package/templates/nextblock-template/app/(auth-pages)/sign-up/page.tsx +46 -46
- package/templates/nextblock-template/app/(auth-pages)/two-factor/page.tsx +51 -51
- package/templates/nextblock-template/app/.well-known/ucp/route.ts +16 -16
- package/templates/nextblock-template/app/actions/consent.ts +57 -57
- package/templates/nextblock-template/app/actions/twoFactorEmail.ts +22 -22
- package/templates/nextblock-template/app/api/ai/cortex/build-widget/route.ts +153 -153
- package/templates/nextblock-template/app/api/ai/generate-blocks/route.ts +96 -96
- package/templates/nextblock-template/app/api/brand/email-logo/route.ts +48 -48
- package/templates/nextblock-template/app/api/checkout/freemius/sync/route.ts +29 -29
- package/templates/nextblock-template/app/api/cms/check-updates/route.ts +44 -44
- package/templates/nextblock-template/app/api/cms/full-backup/export/route.ts +33 -33
- package/templates/nextblock-template/app/api/cms/full-backup/restore/route.ts +63 -63
- package/templates/nextblock-template/app/api/cron/reset-sandbox/route.ts +270 -205
- package/templates/nextblock-template/app/api/cron/reset-sandbox/sandboxResetSql.ts +8096 -7198
- package/templates/nextblock-template/app/api/cron/sync-currencies/route.ts +39 -39
- package/templates/nextblock-template/app/api/custom-blocks/db-relations/route.ts +92 -92
- package/templates/nextblock-template/app/api/custom-blocks/editor-definitions/route.ts +43 -43
- package/templates/nextblock-template/app/api/media/library/route.ts +69 -69
- package/templates/nextblock-template/app/api/media/r2-presigned/route.ts +53 -53
- package/templates/nextblock-template/app/api/visual-editing/block-draft/route.ts +47 -47
- package/templates/nextblock-template/app/api/visual-editing/product-draft/route.ts +47 -47
- package/templates/nextblock-template/app/article/[slug]/PostClientContent.tsx +442 -441
- package/templates/nextblock-template/app/article/[slug]/page.utils.ts +4 -1
- package/templates/nextblock-template/app/checkout/UcpCartHydrator.tsx +20 -20
- package/templates/nextblock-template/app/cms/blocks/components/BlockEditorModal.tsx +241 -241
- package/templates/nextblock-template/app/cms/blocks/components/CustomBlockEditorPreview.tsx +160 -160
- package/templates/nextblock-template/app/cms/blocks/editors/DynamicCustomBlockEditor.tsx +167 -167
- package/templates/nextblock-template/app/cms/components/ConnectGitHubButton.tsx +122 -122
- package/templates/nextblock-template/app/cms/components/CortexAiActiveContext.tsx +23 -23
- package/templates/nextblock-template/app/cms/components/SeoScoreBadge.tsx +3 -3
- package/templates/nextblock-template/app/cms/components/SystemAlertsBanner.tsx +112 -112
- package/templates/nextblock-template/app/cms/components/TablePagination.tsx +136 -136
- package/templates/nextblock-template/app/cms/components/TwoFactorReminderBanner.tsx +45 -45
- package/templates/nextblock-template/app/cms/components/github-connect-actions.ts +102 -102
- package/templates/nextblock-template/app/cms/components/system-alerts-actions.ts +31 -31
- package/templates/nextblock-template/app/cms/coupons/[id]/edit/page.tsx +16 -16
- package/templates/nextblock-template/app/cms/coupons/page.tsx +16 -16
- package/templates/nextblock-template/app/cms/custom-blocks/[id]/edit/page.tsx +66 -66
- package/templates/nextblock-template/app/cms/custom-blocks/actions.ts +519 -519
- package/templates/nextblock-template/app/cms/custom-blocks/components/BlocksLibraryTransferControls.tsx +256 -256
- package/templates/nextblock-template/app/cms/custom-blocks/components/DBRelationSelect.tsx +384 -384
- package/templates/nextblock-template/app/cms/custom-blocks/components/ImageR2Picker.tsx +221 -221
- package/templates/nextblock-template/app/cms/custom-blocks/new/page.tsx +12 -12
- package/templates/nextblock-template/app/cms/custom-blocks/page.tsx +438 -438
- package/templates/nextblock-template/app/cms/dashboard/components/DashboardComponents.tsx +200 -200
- package/templates/nextblock-template/app/cms/dashboard/components/DashboardOnboarding.tsx +130 -130
- package/templates/nextblock-template/app/cms/import-export/actions.ts +226 -226
- package/templates/nextblock-template/app/cms/pages/page.tsx +273 -273
- package/templates/nextblock-template/app/cms/posts/page.tsx +251 -251
- package/templates/nextblock-template/app/cms/products/categories/page.tsx +12 -12
- package/templates/nextblock-template/app/cms/products/new/page.tsx +135 -135
- package/templates/nextblock-template/app/cms/promotions/PromotionsWorkspace.tsx +456 -456
- package/templates/nextblock-template/app/cms/promotions/actions.ts +115 -115
- package/templates/nextblock-template/app/cms/promotions/page.tsx +31 -31
- package/templates/nextblock-template/app/cms/settings/backup-restore/BackupRestoreWorkspace.tsx +1004 -1004
- package/templates/nextblock-template/app/cms/settings/backup-restore/page.tsx +29 -29
- package/templates/nextblock-template/app/cms/settings/bot-protection/page.tsx +24 -24
- package/templates/nextblock-template/app/cms/settings/email/page.tsx +28 -28
- package/templates/nextblock-template/app/cms/settings/extra-translations/actions.ts +276 -276
- package/templates/nextblock-template/app/cms/settings/google-analytics/page.tsx +26 -26
- package/templates/nextblock-template/app/cms/settings/logos/components/DeleteLogoButton.tsx +21 -21
- package/templates/nextblock-template/app/cms/settings/logos/components/SetActiveLogoButton.tsx +42 -42
- package/templates/nextblock-template/app/cms/settings/logos/components/SiteSeoSettingsForm.tsx +133 -133
- package/templates/nextblock-template/app/cms/settings/privacy/page.tsx +27 -27
- package/templates/nextblock-template/app/cms/settings/registration/page.tsx +27 -27
- package/templates/nextblock-template/app/cms/settings/security/page.tsx +33 -33
- package/templates/nextblock-template/app/lib/site-settings.ts +105 -105
- package/templates/nextblock-template/app/lib/ucp/protocol.ts +190 -190
- package/templates/nextblock-template/app/lib/ucp/server.test.ts +56 -56
- package/templates/nextblock-template/app/setup/SetupWizard.tsx +678 -678
- package/templates/nextblock-template/app/setup/layout.tsx +13 -13
- package/templates/nextblock-template/app/setup/page.tsx +111 -111
- package/templates/nextblock-template/app/ucp/v1/carts/[id]/cancel/route.ts +38 -38
- package/templates/nextblock-template/app/ucp/v1/carts/[id]/route.ts +68 -68
- package/templates/nextblock-template/app/ucp/v1/carts/route.ts +35 -35
- package/templates/nextblock-template/app/ucp/v1/catalog/lookup/route.ts +35 -35
- package/templates/nextblock-template/app/ucp/v1/catalog/product/route.ts +35 -35
- package/templates/nextblock-template/app/ucp/v1/catalog/search/route.ts +34 -34
- package/templates/nextblock-template/components/CartTranslator.tsx +210 -210
- package/templates/nextblock-template/components/DeferredCartTranslator.tsx +51 -51
- package/templates/nextblock-template/components/DeferredGlobalSearch.tsx +68 -68
- package/templates/nextblock-template/components/DeferredGoogleAnalytics.tsx +70 -70
- package/templates/nextblock-template/components/FeatureImageHero.tsx +47 -47
- package/templates/nextblock-template/components/GlobalSearch.tsx +557 -557
- package/templates/nextblock-template/components/Header.tsx +38 -38
- package/templates/nextblock-template/components/PublicEnvBootstrap.tsx +30 -30
- package/templates/nextblock-template/components/ResponsiveNav.tsx +14 -14
- package/templates/nextblock-template/components/auth/AuthBotProtection.tsx +182 -182
- package/templates/nextblock-template/components/blocks/PostsGridClient.tsx +48 -48
- package/templates/nextblock-template/components/blocks/TestimonialBlock.tsx +9 -9
- package/templates/nextblock-template/components/blocks/publicRendererLoaders.ts +25 -25
- package/templates/nextblock-template/components/blocks/renderers/ButtonBlockRenderer.tsx +92 -92
- package/templates/nextblock-template/components/blocks/renderers/ClientTextBlockRenderer.tsx +11 -0
- package/templates/nextblock-template/components/blocks/renderers/PostsGridBlockRenderer.tsx +24 -24
- package/templates/nextblock-template/components/blocks/renderers/TestimonialBlockRenderer.tsx +57 -57
- package/templates/nextblock-template/components/blocks/renderers/inline/AlertWidgetRenderer.tsx +2 -2
- package/templates/nextblock-template/components/blocks/renderers/inline/CtaWidgetRenderer.tsx +2 -2
- package/templates/nextblock-template/components/media/YouTubeFacade.tsx +105 -105
- package/templates/nextblock-template/components/media/youtube-embed-replace.tsx +32 -32
- package/templates/nextblock-template/components/privacy/ConsentBanner.tsx +170 -170
- package/templates/nextblock-template/components/privacy/ConsentGatedAnalytics.tsx +70 -70
- package/templates/nextblock-template/components/renderers/CachedDynamicLayoutEngine.tsx +28 -28
- package/templates/nextblock-template/components/renderers/DynamicLayoutEngine.test.tsx +166 -166
- package/templates/nextblock-template/components/renderers/DynamicLayoutEngine.tsx +471 -471
- package/templates/nextblock-template/components/visual-editing/DeferredVisualEditing.tsx +21 -21
- package/templates/nextblock-template/context/language-rest-client.ts +32 -32
- package/templates/nextblock-template/docker/db/init/99-jwt.sql +6 -6
- package/templates/nextblock-template/docker/db/init/99-roles.sql +25 -25
- package/templates/nextblock-template/docker/kong/kong.yml +112 -112
- package/templates/nextblock-template/docs/02-ECOMMERCE-CAPABILITIES.md +364 -364
- package/templates/nextblock-template/docs/04-DATABASE-AND-AUTH.md +11 -0
- package/templates/nextblock-template/docs/07-BLOCK-SDK-AND-EXTENSIBILITY.md +146 -146
- package/templates/nextblock-template/docs/08-NEXTBLOCK-CORTEX-AI-ARCHITECTURE.md +19 -0
- package/templates/nextblock-template/docs/10-CUSTOM-BLOCKS.md +222 -222
- package/templates/nextblock-template/lib/app-secrets.ts +39 -39
- package/templates/nextblock-template/lib/auth/cookies.ts +47 -47
- package/templates/nextblock-template/lib/auth/crypto.ts +45 -45
- package/templates/nextblock-template/lib/auth/trustedDevices.ts +92 -92
- package/templates/nextblock-template/lib/blocks/README.md +13 -13
- package/templates/nextblock-template/lib/botProtection/verify.ts +134 -134
- package/templates/nextblock-template/lib/cms/payments-reminder.test.ts +135 -135
- package/templates/nextblock-template/lib/cms/payments-reminder.ts +105 -105
- package/templates/nextblock-template/lib/cms-transfer/types.ts +145 -145
- package/templates/nextblock-template/lib/custom-block-definitions.ts +87 -87
- package/templates/nextblock-template/lib/custom-block-r2-upload-shared.ts +178 -178
- package/templates/nextblock-template/lib/custom-block-r2-upload.test.ts +140 -140
- package/templates/nextblock-template/lib/custom-block-r2-upload.ts +88 -88
- package/templates/nextblock-template/lib/custom-block-relations.test.ts +227 -227
- package/templates/nextblock-template/lib/custom-block-relations.ts +279 -279
- package/templates/nextblock-template/lib/custom-block-safelist.ts +14 -14
- package/templates/nextblock-template/lib/editor/dynamic-extension-core.test.ts +172 -172
- package/templates/nextblock-template/lib/editor/dynamic-extension-core.ts +213 -213
- package/templates/nextblock-template/lib/editor/dynamic-extension-loader.ts +22 -22
- package/templates/nextblock-template/lib/editor/dynamic-extensions.tsx +193 -193
- package/templates/nextblock-template/lib/email/branding-format.test.ts +133 -133
- package/templates/nextblock-template/lib/email/branding-format.ts +123 -123
- package/templates/nextblock-template/lib/email/branding.ts +76 -76
- package/templates/nextblock-template/lib/full-backup/manifest.test.ts +121 -121
- package/templates/nextblock-template/lib/full-backup/manifest.ts +206 -206
- package/templates/nextblock-template/lib/logos/active-logo.ts +53 -53
- package/templates/nextblock-template/lib/media/resolveMediaUrl.ts +56 -54
- package/templates/nextblock-template/lib/media/youtube.ts +99 -99
- package/templates/nextblock-template/lib/onboarding/actions.ts +31 -31
- package/templates/nextblock-template/lib/privacy/consent-client.ts +57 -57
- package/templates/nextblock-template/lib/privacy/contact-emails.ts +64 -64
- package/templates/nextblock-template/lib/privacy/settings.ts +115 -115
- package/templates/nextblock-template/lib/privacy/types.ts +69 -69
- package/templates/nextblock-template/lib/promotions/server.test.ts +74 -74
- package/templates/nextblock-template/lib/promotions/server.ts +741 -741
- package/templates/nextblock-template/lib/resolve-block-relations.test.ts +142 -142
- package/templates/nextblock-template/lib/resolve-block-relations.ts +255 -255
- package/templates/nextblock-template/lib/seo/page-document.ts +4 -4
- package/templates/nextblock-template/lib/setup/actions.ts +460 -460
- package/templates/nextblock-template/lib/setup/env-status.ts +125 -125
- package/templates/nextblock-template/lib/setup/env-write.ts +111 -111
- package/templates/nextblock-template/lib/setup/migrations-bundle.ts +42 -12
- package/templates/nextblock-template/lib/setup/provisioning.ts +59 -59
- package/templates/nextblock-template/lib/setup/schema-apply.ts +408 -408
- package/templates/nextblock-template/lib/setup/system-config.ts +105 -105
- package/templates/nextblock-template/lib/setup/types.ts +18 -18
- package/templates/nextblock-template/lib/storage/provider.ts +66 -66
- package/templates/nextblock-template/lib/storage/supabase-storage.ts +103 -103
- package/templates/nextblock-template/lib/updates/github-device.ts +206 -206
- package/templates/nextblock-template/lib/updates/repo-identity.ts +56 -56
- package/templates/nextblock-template/lib/visual-editing/draft-content.test.ts +105 -105
- package/templates/nextblock-template/lib/visual-editing/draft-route.test.ts +42 -42
- package/templates/nextblock-template/lib/visual-editing/edit-info.test.ts +143 -143
- package/templates/nextblock-template/lib/visual-editing/edit-info.ts +94 -94
- package/templates/nextblock-template/lib/visual-editing/product-drafts.test.ts +81 -81
- package/templates/nextblock-template/lib/zod-config.ts +5 -5
- package/templates/nextblock-template/next-env.d.ts +1 -0
- package/templates/nextblock-template/package.json +1 -1
- package/templates/nextblock-template/public/images/cortex_post.webp +0 -0
- package/templates/nextblock-template/public/images/update_nextblock.webp +0 -0
- package/templates/nextblock-template/scripts/docker-setup.mjs +310 -310
- package/templates/nextblock-template/scripts/validate-editor-block-schema.ts +112 -112
- package/templates/nextblock-template/scripts/verify-cortex-ai-build-widget.tsx +98 -98
- package/templates/nextblock-template/scripts/verify-cortex-ai-generate-blocks.ts +62 -62
- package/templates/nextblock-template/scripts/verify-cortex-ai-global-tools.ts +537 -537
- package/templates/nextblock-template/scripts/verify-cortex-ai-routing.ts +58 -58
- package/templates/nextblock-template/scripts/verify-custom-block-definitions.ts +188 -188
- package/templates/nextblock-template/scripts/verify-dynamic-custom-block-extensions.ts +123 -123
- package/templates/nextblock-template/scripts/verify-dynamic-layout-engine.tsx +133 -133
- package/templates/nextblock-template/scripts/verify-milestone-2-custom-blocks.ts +65 -65
- package/templates/nextblock-template/tools/deploy-supabase.js +159 -159
- package/templates/nextblock-template/types/jsdom.d.ts +6 -6
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
/* eslint-disable @nx/enforce-module-boundaries */
|
|
2
|
-
import dotenv from 'dotenv';
|
|
3
|
-
import { createClient } from '@supabase/supabase-js';
|
|
4
|
-
import { toJSONSchema } from 'zod';
|
|
5
|
-
import {
|
|
6
|
-
editorBlockDocumentSchema,
|
|
7
|
-
editorGeneratedBlockDocumentSchema,
|
|
8
|
-
getEditorBlocksJsonSchema,
|
|
9
|
-
} from '../../../libs/utils/src/lib/editor-blocks';
|
|
10
|
-
|
|
11
|
-
dotenv.config({ path: '.env.local' });
|
|
12
|
-
|
|
13
|
-
const seededProductDescriptionSample = {
|
|
14
|
-
type: 'doc',
|
|
15
|
-
content: [
|
|
16
|
-
{
|
|
17
|
-
type: 'heading',
|
|
18
|
-
attrs: { level: 2 },
|
|
19
|
-
content: [{ type: 'text', text: 'Studio uniform for shipping days' }],
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
type: 'paragraph',
|
|
23
|
-
content: [
|
|
24
|
-
{
|
|
25
|
-
type: 'text',
|
|
26
|
-
text: 'The NextBlock Studio Tee is cut from premium heavyweight cotton.',
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
type: 'bulletList',
|
|
32
|
-
content: [
|
|
33
|
-
{
|
|
34
|
-
type: 'listItem',
|
|
35
|
-
content: [
|
|
36
|
-
{
|
|
37
|
-
type: 'paragraph',
|
|
38
|
-
content: [{ type: 'text', text: 'Heavyweight cotton feel.' }],
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
},
|
|
42
|
-
],
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
async function readDatabaseSample() {
|
|
48
|
-
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
|
|
49
|
-
const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
|
50
|
-
|
|
51
|
-
if (!supabaseUrl || !serviceRoleKey) {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const supabase = createClient(supabaseUrl, serviceRoleKey, {
|
|
56
|
-
auth: {
|
|
57
|
-
autoRefreshToken: false,
|
|
58
|
-
persistSession: false,
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const { data, error } = await supabase
|
|
63
|
-
.from('products')
|
|
64
|
-
.select('id, slug, description_json')
|
|
65
|
-
.not('description_json', 'is', null)
|
|
66
|
-
.limit(1)
|
|
67
|
-
.maybeSingle();
|
|
68
|
-
|
|
69
|
-
if (error) {
|
|
70
|
-
throw new Error(`Failed to read product description_json sample: ${error.message}`);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return data;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async function main() {
|
|
77
|
-
if (process.argv.includes('--generated-schema-diagnostics')) {
|
|
78
|
-
const jsonSchema = toJSONSchema(editorGeneratedBlockDocumentSchema, {
|
|
79
|
-
cycles: 'ref',
|
|
80
|
-
reused: 'ref',
|
|
81
|
-
target: 'draft-07',
|
|
82
|
-
});
|
|
83
|
-
const schemaText = JSON.stringify(jsonSchema);
|
|
84
|
-
console.log(`Generated schema propertyNames occurrences=${schemaText.match(/propertyNames/g)?.length || 0}`);
|
|
85
|
-
console.log(`Generated schema size=${schemaText.length}`);
|
|
86
|
-
const propertyNamesIndex = schemaText.indexOf('propertyNames');
|
|
87
|
-
if (propertyNamesIndex >= 0) {
|
|
88
|
-
console.log(schemaText.slice(Math.max(0, propertyNamesIndex - 240), propertyNamesIndex + 240));
|
|
89
|
-
}
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const databaseSample = await readDatabaseSample();
|
|
94
|
-
const sample = databaseSample?.description_json || seededProductDescriptionSample;
|
|
95
|
-
const parsed = editorBlockDocumentSchema.parse(sample);
|
|
96
|
-
const jsonSchema = getEditorBlocksJsonSchema();
|
|
97
|
-
|
|
98
|
-
console.log('Editor block schema validation succeeded.');
|
|
99
|
-
console.log(
|
|
100
|
-
databaseSample
|
|
101
|
-
? `Sample source=products.description_json slug=${databaseSample.slug}`
|
|
102
|
-
: 'Sample source=seeded product description fallback'
|
|
103
|
-
);
|
|
104
|
-
console.log(`Root type=${parsed.type}`);
|
|
105
|
-
console.log(`Top-level blocks=${parsed.content?.length || 0}`);
|
|
106
|
-
console.log(`JSON Schema keys=${Object.keys(jsonSchema as Record<string, unknown>).join(',')}`);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
main().catch((error) => {
|
|
110
|
-
console.error(error instanceof Error ? error.message : error);
|
|
111
|
-
process.exitCode = 1;
|
|
112
|
-
});
|
|
1
|
+
/* eslint-disable @nx/enforce-module-boundaries */
|
|
2
|
+
import dotenv from 'dotenv';
|
|
3
|
+
import { createClient } from '@supabase/supabase-js';
|
|
4
|
+
import { toJSONSchema } from 'zod';
|
|
5
|
+
import {
|
|
6
|
+
editorBlockDocumentSchema,
|
|
7
|
+
editorGeneratedBlockDocumentSchema,
|
|
8
|
+
getEditorBlocksJsonSchema,
|
|
9
|
+
} from '../../../libs/utils/src/lib/editor-blocks';
|
|
10
|
+
|
|
11
|
+
dotenv.config({ path: '.env.local' });
|
|
12
|
+
|
|
13
|
+
const seededProductDescriptionSample = {
|
|
14
|
+
type: 'doc',
|
|
15
|
+
content: [
|
|
16
|
+
{
|
|
17
|
+
type: 'heading',
|
|
18
|
+
attrs: { level: 2 },
|
|
19
|
+
content: [{ type: 'text', text: 'Studio uniform for shipping days' }],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
type: 'paragraph',
|
|
23
|
+
content: [
|
|
24
|
+
{
|
|
25
|
+
type: 'text',
|
|
26
|
+
text: 'The NextBlock Studio Tee is cut from premium heavyweight cotton.',
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: 'bulletList',
|
|
32
|
+
content: [
|
|
33
|
+
{
|
|
34
|
+
type: 'listItem',
|
|
35
|
+
content: [
|
|
36
|
+
{
|
|
37
|
+
type: 'paragraph',
|
|
38
|
+
content: [{ type: 'text', text: 'Heavyweight cotton feel.' }],
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
async function readDatabaseSample() {
|
|
48
|
+
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
|
|
49
|
+
const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
|
50
|
+
|
|
51
|
+
if (!supabaseUrl || !serviceRoleKey) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const supabase = createClient(supabaseUrl, serviceRoleKey, {
|
|
56
|
+
auth: {
|
|
57
|
+
autoRefreshToken: false,
|
|
58
|
+
persistSession: false,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const { data, error } = await supabase
|
|
63
|
+
.from('products')
|
|
64
|
+
.select('id, slug, description_json')
|
|
65
|
+
.not('description_json', 'is', null)
|
|
66
|
+
.limit(1)
|
|
67
|
+
.maybeSingle();
|
|
68
|
+
|
|
69
|
+
if (error) {
|
|
70
|
+
throw new Error(`Failed to read product description_json sample: ${error.message}`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return data;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function main() {
|
|
77
|
+
if (process.argv.includes('--generated-schema-diagnostics')) {
|
|
78
|
+
const jsonSchema = toJSONSchema(editorGeneratedBlockDocumentSchema, {
|
|
79
|
+
cycles: 'ref',
|
|
80
|
+
reused: 'ref',
|
|
81
|
+
target: 'draft-07',
|
|
82
|
+
});
|
|
83
|
+
const schemaText = JSON.stringify(jsonSchema);
|
|
84
|
+
console.log(`Generated schema propertyNames occurrences=${schemaText.match(/propertyNames/g)?.length || 0}`);
|
|
85
|
+
console.log(`Generated schema size=${schemaText.length}`);
|
|
86
|
+
const propertyNamesIndex = schemaText.indexOf('propertyNames');
|
|
87
|
+
if (propertyNamesIndex >= 0) {
|
|
88
|
+
console.log(schemaText.slice(Math.max(0, propertyNamesIndex - 240), propertyNamesIndex + 240));
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const databaseSample = await readDatabaseSample();
|
|
94
|
+
const sample = databaseSample?.description_json || seededProductDescriptionSample;
|
|
95
|
+
const parsed = editorBlockDocumentSchema.parse(sample);
|
|
96
|
+
const jsonSchema = getEditorBlocksJsonSchema();
|
|
97
|
+
|
|
98
|
+
console.log('Editor block schema validation succeeded.');
|
|
99
|
+
console.log(
|
|
100
|
+
databaseSample
|
|
101
|
+
? `Sample source=products.description_json slug=${databaseSample.slug}`
|
|
102
|
+
: 'Sample source=seeded product description fallback'
|
|
103
|
+
);
|
|
104
|
+
console.log(`Root type=${parsed.type}`);
|
|
105
|
+
console.log(`Top-level blocks=${parsed.content?.length || 0}`);
|
|
106
|
+
console.log(`JSON Schema keys=${Object.keys(jsonSchema as Record<string, unknown>).join(',')}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
main().catch((error) => {
|
|
110
|
+
console.error(error instanceof Error ? error.message : error);
|
|
111
|
+
process.exitCode = 1;
|
|
112
|
+
});
|
|
@@ -1,98 +1,98 @@
|
|
|
1
|
-
import dotenv from 'dotenv';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import { renderToStaticMarkup } from 'react-dom/server';
|
|
4
|
-
|
|
5
|
-
import { DynamicLayoutEngine } from '../components/renderers/DynamicLayoutEngine';
|
|
6
|
-
import {
|
|
7
|
-
buildCortexWidgetDefinitionInsertPayload,
|
|
8
|
-
buildCortexProfileCardVerificationDefinition,
|
|
9
|
-
validateCortexWidgetDefinitionOutput,
|
|
10
|
-
} from '@nextblock-cms/cortex';
|
|
11
|
-
|
|
12
|
-
dotenv.config({ path: '.env.local' });
|
|
13
|
-
|
|
14
|
-
const args = process.argv.slice(2);
|
|
15
|
-
const prompt =
|
|
16
|
-
args.filter((arg) => !arg.startsWith('--')).join(' ') ||
|
|
17
|
-
'Synthesize a multi-tier profile card with an inner flex column housing an R2 picture asset slot and a customer list relation link.';
|
|
18
|
-
|
|
19
|
-
function renderVerificationHtml(definition: ReturnType<typeof validateCortexWidgetDefinitionOutput>) {
|
|
20
|
-
return renderToStaticMarkup(
|
|
21
|
-
<DynamicLayoutEngine
|
|
22
|
-
definition={{
|
|
23
|
-
fields: definition.fields,
|
|
24
|
-
id: '77777777-7777-4777-8777-777777777777',
|
|
25
|
-
layout_schema: definition.layout_schema,
|
|
26
|
-
name: definition.name,
|
|
27
|
-
slug: definition.slug,
|
|
28
|
-
}}
|
|
29
|
-
data={{
|
|
30
|
-
customer_list: ['profile-1', 'profile-2'],
|
|
31
|
-
profile_name: 'Ada Lovelace',
|
|
32
|
-
profile_photo: {
|
|
33
|
-
alt: 'Ada Lovelace profile photo',
|
|
34
|
-
object_key: 'cortex/profile-card/ada.webp',
|
|
35
|
-
url: 'https://cdn.nextblock.dev/cortex/profile-card/ada.webp',
|
|
36
|
-
},
|
|
37
|
-
profile_role: 'Principal Architect',
|
|
38
|
-
profile_summary:
|
|
39
|
-
'<p>Builds multi-tier product systems with direct media and live relation data.</p>',
|
|
40
|
-
resolved_relations: {
|
|
41
|
-
customer_list: [
|
|
42
|
-
{
|
|
43
|
-
record: { full_name: 'Analytical Engine Society', id: 'profile-1' },
|
|
44
|
-
table: 'profiles',
|
|
45
|
-
value: 'profile-1',
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
record: { full_name: 'Difference Labs', id: 'profile-2' },
|
|
49
|
-
table: 'profiles',
|
|
50
|
-
value: 'profile-2',
|
|
51
|
-
},
|
|
52
|
-
],
|
|
53
|
-
},
|
|
54
|
-
}}
|
|
55
|
-
/>
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async function main() {
|
|
60
|
-
const definition = validateCortexWidgetDefinitionOutput(
|
|
61
|
-
buildCortexProfileCardVerificationDefinition()
|
|
62
|
-
);
|
|
63
|
-
const payload = buildCortexWidgetDefinitionInsertPayload(definition);
|
|
64
|
-
const html = renderVerificationHtml(definition);
|
|
65
|
-
|
|
66
|
-
console.log(
|
|
67
|
-
JSON.stringify(
|
|
68
|
-
{
|
|
69
|
-
atomicInsert: {
|
|
70
|
-
payload,
|
|
71
|
-
status: 'validated-payload',
|
|
72
|
-
},
|
|
73
|
-
fieldTypes: definition.fields.map((field) => ({
|
|
74
|
-
key: field.key,
|
|
75
|
-
type: field.type,
|
|
76
|
-
})),
|
|
77
|
-
prompt,
|
|
78
|
-
renderChecks: {
|
|
79
|
-
containsCustomerRelations:
|
|
80
|
-
html.includes('Analytical Engine Society') && html.includes('Difference Labs'),
|
|
81
|
-
containsImageSlot: html.includes('cortex/profile-card/ada.webp'),
|
|
82
|
-
containsNestedTailwind:
|
|
83
|
-
html.includes('flex flex-col gap-6 md:flex-row') &&
|
|
84
|
-
html.includes('flex min-w-0 flex-1 flex-col gap-4'),
|
|
85
|
-
htmlLength: html.length,
|
|
86
|
-
},
|
|
87
|
-
slug: definition.slug,
|
|
88
|
-
},
|
|
89
|
-
null,
|
|
90
|
-
2
|
|
91
|
-
)
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
main().catch((error) => {
|
|
96
|
-
console.error(error instanceof Error ? error.message : error);
|
|
97
|
-
process.exitCode = 1;
|
|
98
|
-
});
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
4
|
+
|
|
5
|
+
import { DynamicLayoutEngine } from '../components/renderers/DynamicLayoutEngine';
|
|
6
|
+
import {
|
|
7
|
+
buildCortexWidgetDefinitionInsertPayload,
|
|
8
|
+
buildCortexProfileCardVerificationDefinition,
|
|
9
|
+
validateCortexWidgetDefinitionOutput,
|
|
10
|
+
} from '@nextblock-cms/cortex';
|
|
11
|
+
|
|
12
|
+
dotenv.config({ path: '.env.local' });
|
|
13
|
+
|
|
14
|
+
const args = process.argv.slice(2);
|
|
15
|
+
const prompt =
|
|
16
|
+
args.filter((arg) => !arg.startsWith('--')).join(' ') ||
|
|
17
|
+
'Synthesize a multi-tier profile card with an inner flex column housing an R2 picture asset slot and a customer list relation link.';
|
|
18
|
+
|
|
19
|
+
function renderVerificationHtml(definition: ReturnType<typeof validateCortexWidgetDefinitionOutput>) {
|
|
20
|
+
return renderToStaticMarkup(
|
|
21
|
+
<DynamicLayoutEngine
|
|
22
|
+
definition={{
|
|
23
|
+
fields: definition.fields,
|
|
24
|
+
id: '77777777-7777-4777-8777-777777777777',
|
|
25
|
+
layout_schema: definition.layout_schema,
|
|
26
|
+
name: definition.name,
|
|
27
|
+
slug: definition.slug,
|
|
28
|
+
}}
|
|
29
|
+
data={{
|
|
30
|
+
customer_list: ['profile-1', 'profile-2'],
|
|
31
|
+
profile_name: 'Ada Lovelace',
|
|
32
|
+
profile_photo: {
|
|
33
|
+
alt: 'Ada Lovelace profile photo',
|
|
34
|
+
object_key: 'cortex/profile-card/ada.webp',
|
|
35
|
+
url: 'https://cdn.nextblock.dev/cortex/profile-card/ada.webp',
|
|
36
|
+
},
|
|
37
|
+
profile_role: 'Principal Architect',
|
|
38
|
+
profile_summary:
|
|
39
|
+
'<p>Builds multi-tier product systems with direct media and live relation data.</p>',
|
|
40
|
+
resolved_relations: {
|
|
41
|
+
customer_list: [
|
|
42
|
+
{
|
|
43
|
+
record: { full_name: 'Analytical Engine Society', id: 'profile-1' },
|
|
44
|
+
table: 'profiles',
|
|
45
|
+
value: 'profile-1',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
record: { full_name: 'Difference Labs', id: 'profile-2' },
|
|
49
|
+
table: 'profiles',
|
|
50
|
+
value: 'profile-2',
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
}}
|
|
55
|
+
/>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function main() {
|
|
60
|
+
const definition = validateCortexWidgetDefinitionOutput(
|
|
61
|
+
buildCortexProfileCardVerificationDefinition()
|
|
62
|
+
);
|
|
63
|
+
const payload = buildCortexWidgetDefinitionInsertPayload(definition);
|
|
64
|
+
const html = renderVerificationHtml(definition);
|
|
65
|
+
|
|
66
|
+
console.log(
|
|
67
|
+
JSON.stringify(
|
|
68
|
+
{
|
|
69
|
+
atomicInsert: {
|
|
70
|
+
payload,
|
|
71
|
+
status: 'validated-payload',
|
|
72
|
+
},
|
|
73
|
+
fieldTypes: definition.fields.map((field) => ({
|
|
74
|
+
key: field.key,
|
|
75
|
+
type: field.type,
|
|
76
|
+
})),
|
|
77
|
+
prompt,
|
|
78
|
+
renderChecks: {
|
|
79
|
+
containsCustomerRelations:
|
|
80
|
+
html.includes('Analytical Engine Society') && html.includes('Difference Labs'),
|
|
81
|
+
containsImageSlot: html.includes('cortex/profile-card/ada.webp'),
|
|
82
|
+
containsNestedTailwind:
|
|
83
|
+
html.includes('flex flex-col gap-6 md:flex-row') &&
|
|
84
|
+
html.includes('flex min-w-0 flex-1 flex-col gap-4'),
|
|
85
|
+
htmlLength: html.length,
|
|
86
|
+
},
|
|
87
|
+
slug: definition.slug,
|
|
88
|
+
},
|
|
89
|
+
null,
|
|
90
|
+
2
|
|
91
|
+
)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
main().catch((error) => {
|
|
96
|
+
console.error(error instanceof Error ? error.message : error);
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
});
|
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
import dotenv from 'dotenv';
|
|
2
|
-
|
|
3
|
-
import { generateEditorHtmlFragment } from '@nextblock-cms/cortex';
|
|
4
|
-
|
|
5
|
-
dotenv.config({ path: '.env.local' });
|
|
6
|
-
|
|
7
|
-
const args = process.argv.slice(2);
|
|
8
|
-
const modelFlag = args.find((arg) => arg.startsWith('--model='));
|
|
9
|
-
const prompt =
|
|
10
|
-
args.filter((arg) => !arg.startsWith('--model=')).join(' ') ||
|
|
11
|
-
'Generate a 3-tier pricing table';
|
|
12
|
-
const modelId = modelFlag?.slice('--model='.length);
|
|
13
|
-
|
|
14
|
-
async function main() {
|
|
15
|
-
const result = await generateEditorHtmlFragment({
|
|
16
|
-
fallbackModelIds: modelId ? [] : undefined,
|
|
17
|
-
modelId,
|
|
18
|
-
prompt,
|
|
19
|
-
});
|
|
20
|
-
const hasTable = /<table\b/i.test(result.html);
|
|
21
|
-
|
|
22
|
-
console.log(result.html);
|
|
23
|
-
console.error(
|
|
24
|
-
JSON.stringify(
|
|
25
|
-
{
|
|
26
|
-
attempts: result.attempts.map((attempt) => ({
|
|
27
|
-
modelId: attempt.modelId,
|
|
28
|
-
status: attempt.status,
|
|
29
|
-
})),
|
|
30
|
-
credentialSource: result.credentialSource,
|
|
31
|
-
hasTable,
|
|
32
|
-
modelId: result.modelId,
|
|
33
|
-
outputCharacters: result.html.length,
|
|
34
|
-
},
|
|
35
|
-
null,
|
|
36
|
-
2
|
|
37
|
-
)
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
main().catch((error) => {
|
|
42
|
-
if (error && typeof error === 'object' && 'attempts' in error) {
|
|
43
|
-
console.error(JSON.stringify((error as { attempts: unknown }).attempts, null, 2));
|
|
44
|
-
}
|
|
45
|
-
if (error && typeof error === 'object' && 'cause' in error) {
|
|
46
|
-
const cause = (error as { cause?: { cause?: unknown; message?: string; text?: string } }).cause;
|
|
47
|
-
console.error(
|
|
48
|
-
JSON.stringify(
|
|
49
|
-
{
|
|
50
|
-
cause: cause?.message,
|
|
51
|
-
causeCause:
|
|
52
|
-
cause?.cause instanceof Error ? cause.cause.message : String(cause?.cause || ''),
|
|
53
|
-
text: cause?.text,
|
|
54
|
-
},
|
|
55
|
-
null,
|
|
56
|
-
2
|
|
57
|
-
)
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
console.error(error instanceof Error ? error.message : error);
|
|
61
|
-
process.exitCode = 1;
|
|
62
|
-
});
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
|
|
3
|
+
import { generateEditorHtmlFragment } from '@nextblock-cms/cortex';
|
|
4
|
+
|
|
5
|
+
dotenv.config({ path: '.env.local' });
|
|
6
|
+
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
const modelFlag = args.find((arg) => arg.startsWith('--model='));
|
|
9
|
+
const prompt =
|
|
10
|
+
args.filter((arg) => !arg.startsWith('--model=')).join(' ') ||
|
|
11
|
+
'Generate a 3-tier pricing table';
|
|
12
|
+
const modelId = modelFlag?.slice('--model='.length);
|
|
13
|
+
|
|
14
|
+
async function main() {
|
|
15
|
+
const result = await generateEditorHtmlFragment({
|
|
16
|
+
fallbackModelIds: modelId ? [] : undefined,
|
|
17
|
+
modelId,
|
|
18
|
+
prompt,
|
|
19
|
+
});
|
|
20
|
+
const hasTable = /<table\b/i.test(result.html);
|
|
21
|
+
|
|
22
|
+
console.log(result.html);
|
|
23
|
+
console.error(
|
|
24
|
+
JSON.stringify(
|
|
25
|
+
{
|
|
26
|
+
attempts: result.attempts.map((attempt) => ({
|
|
27
|
+
modelId: attempt.modelId,
|
|
28
|
+
status: attempt.status,
|
|
29
|
+
})),
|
|
30
|
+
credentialSource: result.credentialSource,
|
|
31
|
+
hasTable,
|
|
32
|
+
modelId: result.modelId,
|
|
33
|
+
outputCharacters: result.html.length,
|
|
34
|
+
},
|
|
35
|
+
null,
|
|
36
|
+
2
|
|
37
|
+
)
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
main().catch((error) => {
|
|
42
|
+
if (error && typeof error === 'object' && 'attempts' in error) {
|
|
43
|
+
console.error(JSON.stringify((error as { attempts: unknown }).attempts, null, 2));
|
|
44
|
+
}
|
|
45
|
+
if (error && typeof error === 'object' && 'cause' in error) {
|
|
46
|
+
const cause = (error as { cause?: { cause?: unknown; message?: string; text?: string } }).cause;
|
|
47
|
+
console.error(
|
|
48
|
+
JSON.stringify(
|
|
49
|
+
{
|
|
50
|
+
cause: cause?.message,
|
|
51
|
+
causeCause:
|
|
52
|
+
cause?.cause instanceof Error ? cause.cause.message : String(cause?.cause || ''),
|
|
53
|
+
text: cause?.text,
|
|
54
|
+
},
|
|
55
|
+
null,
|
|
56
|
+
2
|
|
57
|
+
)
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
console.error(error instanceof Error ? error.message : error);
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
});
|