Skip to content

Commit b2bd48e

Browse files
committed
fix(spec): anchor the Schema-suffix strip when deriving published schema names (#4592)
build-schemas.ts and build-docs.ts derived the published JSON Schema name via key.replace('Schema', '') — a string pattern, which replaces the FIRST occurrence. Consts with 'Schema' in prefix/middle position (SchemaModeSchema, SchemaChangeSchema, SchemaLevelIsolationStrategySchema, DocumentSchemaValidationSchema) lost an inner segment instead of the suffix, publishing $id URLs, manifest keys and docs sections under type names that exist nowhere in the export surface. - extract the mapping into scripts/lib/schema-name.ts (schemaNameFromExportKey, /Schema$/ anchored) shared by both generators, with a pin test covering the four mangled names - swap the 4 stale json-schema.manifest.json keys for the corrected ones (deliberate retirement per #2978 — the old names never named a real type) - rename the 14 affected authorable-surface.json key prefixes (rename, not a key retirement: every authorable key survives under the corrected name) - shrink docs-import-surface.baseline.json 152 -> 144 (the 4 'no schema const export' / 'no type export' pairs are gaps that no longer exist) - regenerate the 4 reference-doc pages: sections renamed, real import examples restored Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012C2cd7tL8QDoZ2QKN3djJ5
1 parent 868718e commit b2bd48e

12 files changed

Lines changed: 172 additions & 71 deletions
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
"@objectstack/spec": patch
3+
---
4+
5+
fix(spec): strip the `Schema` suffix by anchored regex when deriving published JSON Schema names (#4592)
6+
7+
`build-schemas.ts` / `build-docs.ts` turned an exported const name into its
8+
published schema name with `key.replace('Schema', '')` — a **string** pattern,
9+
which replaces the FIRST occurrence. Every const whose name also contains
10+
`Schema` in prefix/middle position lost that inner segment instead of its
11+
suffix, so four schemas were published — `$id` URL, `json-schema.manifest.json`
12+
key, docs page section, and import example — under type names that exist
13+
nowhere in the export surface. Both generators now share one anchored helper
14+
(`schemaNameFromExportKey`, `key.replace(/Schema$/, '')`).
15+
16+
Corrected names, FROM → TO (the fix if you referenced an old `$id` under
17+
`https://schema.objectstack.io/v17/...` is to swap in the new name — the TS
18+
exports themselves never changed):
19+
20+
| exported const | old (wrong) schema name | new schema name |
21+
|:---|:---|:---|
22+
| `SchemaModeSchema` | `data/ModeSchema` | `data/SchemaMode` |
23+
| `SchemaChangeSchema` | `system/ChangeSchema` | `system/SchemaChange` |
24+
| `SchemaLevelIsolationStrategySchema` | `system/LevelIsolationStrategySchema` | `system/SchemaLevelIsolationStrategy` |
25+
| `DocumentSchemaValidationSchema` | `data/DocumentValidationSchema` | `data/DocumentSchemaValidation` |
26+
27+
The four old manifest keys are removed as a deliberate retirement per the
28+
#2978 rule (they never named a real exported type), and the four
29+
`no schema const export` / `no type export` pairs they caused in
30+
`docs-import-surface.baseline.json` are deleted (152 → 144 accepted gaps) —
31+
the four reference-doc pages regain real, compilable import examples.

content/docs/references/data/datasource.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ Can be a built-in driver or a plugin-contributed driver (e.g., "com.vendor.snowf
1616
## TypeScript Usage
1717

1818
```typescript
19-
import { DatasourceSchema, DriverDefinitionSchema, DriverType, ExternalDatasourceSettingsSchema } from '@objectstack/spec/data';
20-
import type { Datasource, DriverDefinition, ExternalDatasourceSettings } from '@objectstack/spec/data';
19+
import { DatasourceSchema, DriverDefinitionSchema, DriverType, ExternalDatasourceSettingsSchema, SchemaModeSchema } from '@objectstack/spec/data';
20+
import type { Datasource, DriverDefinition, ExternalDatasourceSettings, SchemaMode } from '@objectstack/spec/data';
2121

2222
// Validate data
2323
const result = DatasourceSchema.parse(data);
@@ -93,7 +93,7 @@ External datasource federation settings (schemaMode != "managed")
9393

9494
---
9595

96-
## ModeSchema
96+
## SchemaMode
9797

9898
Schema ownership mode
9999

content/docs/references/data/driver-nosql.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ Supported NoSQL database types
1616
## TypeScript Usage
1717

1818
```typescript
19-
import { AggregationPipelineSchema, AggregationStageSchema, ConsistencyLevelSchema, NoSQLDataTypeMappingSchema, NoSQLDatabaseTypeSchema, NoSQLDriverConfigSchema, NoSQLIndexSchema, NoSQLIndexTypeSchema, NoSQLOperationTypeSchema, NoSQLQueryOptionsSchema, NoSQLTransactionOptionsSchema, ReplicationConfigSchema, ShardingConfigSchema } from '@objectstack/spec/data';
20-
import type { AggregationPipeline, AggregationStage, ConsistencyLevel, NoSQLDataTypeMapping, NoSQLDatabaseType, NoSQLDriverConfig, NoSQLIndex, NoSQLIndexType, NoSQLOperationType, NoSQLQueryOptions, NoSQLTransactionOptions, ReplicationConfig, ShardingConfig } from '@objectstack/spec/data';
19+
import { AggregationPipelineSchema, AggregationStageSchema, ConsistencyLevelSchema, DocumentSchemaValidationSchema, NoSQLDataTypeMappingSchema, NoSQLDatabaseTypeSchema, NoSQLDriverConfigSchema, NoSQLIndexSchema, NoSQLIndexTypeSchema, NoSQLOperationTypeSchema, NoSQLQueryOptionsSchema, NoSQLTransactionOptionsSchema, ReplicationConfigSchema, ShardingConfigSchema } from '@objectstack/spec/data';
20+
import type { AggregationPipeline, AggregationStage, ConsistencyLevel, DocumentSchemaValidation, NoSQLDataTypeMapping, NoSQLDatabaseType, NoSQLDriverConfig, NoSQLIndex, NoSQLIndexType, NoSQLOperationType, NoSQLQueryOptions, NoSQLTransactionOptions, ReplicationConfig, ShardingConfig } from '@objectstack/spec/data';
2121

2222
// Validate data
2323
const result = AggregationPipelineSchema.parse(data);
@@ -64,7 +64,7 @@ const result = AggregationPipelineSchema.parse(data);
6464

6565
---
6666

67-
## DocumentValidationSchema
67+
## DocumentSchemaValidation
6868

6969
### Properties
7070

content/docs/references/system/deploy-bundle.mdx

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,13 @@ Target: 2-5 second deploys vs. 2-15 minute traditional Docker/CI/CD.
2828
## TypeScript Usage
2929

3030
```typescript
31-
import { DeployBundleSchema, DeployDiffSchema, DeployManifestSchema, DeployStatusEnum, DeployValidationIssueSchema, DeployValidationResultSchema, MigrationPlanSchema, MigrationStatementSchema } from '@objectstack/spec/system';
32-
import type { DeployBundle, DeployDiff, DeployManifest, DeployValidationIssue, DeployValidationResult, MigrationPlan, MigrationStatement } from '@objectstack/spec/system';
31+
import { DeployBundleSchema, DeployDiffSchema, DeployManifestSchema, DeployStatusEnum, DeployValidationIssueSchema, DeployValidationResultSchema, MigrationPlanSchema, MigrationStatementSchema, SchemaChangeSchema } from '@objectstack/spec/system';
32+
import type { DeployBundle, DeployDiff, DeployManifest, DeployValidationIssue, DeployValidationResult, MigrationPlan, MigrationStatement, SchemaChange } from '@objectstack/spec/system';
3333

3434
// Validate data
3535
const result = DeployBundleSchema.parse(data);
3636
```
3737

38-
---
39-
40-
## ChangeSchema
41-
42-
Individual schema change
43-
44-
### Properties
45-
46-
| Property | Type | Required | Description |
47-
| :--- | :--- | :--- | :--- |
48-
| **entityType** | `Enum<'object' \| 'field' \| 'index' \| 'view' \| 'flow' \| 'permission'>` || Entity type |
49-
| **entityName** | `string` || Entity name |
50-
| **parentEntity** | `string` | optional | Parent entity name |
51-
| **changeType** | `Enum<'added' \| 'modified' \| 'removed'>` || Change type |
52-
| **oldValue** | `any` | optional | Previous value |
53-
| **newValue** | `any` | optional | New value |
54-
55-
5638
---
5739

5840
## DeployBundle
@@ -188,3 +170,21 @@ Single DDL migration statement
188170

189171
---
190172

173+
## SchemaChange
174+
175+
Individual schema change
176+
177+
### Properties
178+
179+
| Property | Type | Required | Description |
180+
| :--- | :--- | :--- | :--- |
181+
| **entityType** | `Enum<'object' \| 'field' \| 'index' \| 'view' \| 'flow' \| 'permission'>` || Entity type |
182+
| **entityName** | `string` || Entity name |
183+
| **parentEntity** | `string` | optional | Parent entity name |
184+
| **changeType** | `Enum<'added' \| 'modified' \| 'removed'>` || Change type |
185+
| **oldValue** | `any` | optional | Previous value |
186+
| **newValue** | `any` | optional | New value |
187+
188+
189+
---
190+

content/docs/references/system/tenant.mdx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ Isolation Levels:
2828
## TypeScript Usage
2929

3030
```typescript
31-
import { DatabaseLevelIsolationStrategySchema, DatabaseProviderSchema, QuotaEnforcementResultSchema, RowLevelIsolationStrategySchema, TenantSchema, TenantConnectionConfigSchema, TenantIsolationConfigSchema, TenantIsolationLevel, TenantQuotaSchema, TenantSecurityPolicySchema, TenantUsageSchema } from '@objectstack/spec/system';
32-
import type { DatabaseLevelIsolationStrategy, DatabaseProvider, QuotaEnforcementResult, RowLevelIsolationStrategy, Tenant, TenantConnectionConfig, TenantIsolationConfig, TenantIsolationLevel, TenantQuota, TenantSecurityPolicy, TenantUsage } from '@objectstack/spec/system';
31+
import { DatabaseLevelIsolationStrategySchema, DatabaseProviderSchema, QuotaEnforcementResultSchema, RowLevelIsolationStrategySchema, SchemaLevelIsolationStrategySchema, TenantSchema, TenantConnectionConfigSchema, TenantIsolationConfigSchema, TenantIsolationLevel, TenantQuotaSchema, TenantSecurityPolicySchema, TenantUsageSchema } from '@objectstack/spec/system';
32+
import type { DatabaseLevelIsolationStrategy, DatabaseProvider, QuotaEnforcementResult, RowLevelIsolationStrategy, SchemaLevelIsolationStrategy, Tenant, TenantConnectionConfig, TenantIsolationConfig, TenantIsolationLevel, TenantQuota, TenantSecurityPolicy, TenantUsage } from '@objectstack/spec/system';
3333

3434
// Validate data
3535
const result = DatabaseLevelIsolationStrategySchema.parse(data);
@@ -63,20 +63,6 @@ Database provider for tenant data
6363
* `memory`
6464

6565

66-
---
67-
68-
## LevelIsolationStrategySchema
69-
70-
### Properties
71-
72-
| Property | Type | Required | Description |
73-
| :--- | :--- | :--- | :--- |
74-
| **strategy** | `'isolated_schema'` || Schema-level isolation strategy |
75-
| **schema** | `{ namingPattern: string; includePublicSchema: boolean; sharedSchema: string; autoCreateSchema: boolean }` | optional | Schema configuration |
76-
| **migrations** | `{ strategy: Enum<'parallel' \| 'sequential' \| 'on_demand'>; maxConcurrent: integer; rollbackOnError: boolean }` | optional | Migration configuration |
77-
| **performance** | `{ poolPerSchema: boolean; schemaCacheTTL: integer }` | optional | Performance settings |
78-
79-
8066
---
8167

8268
## QuotaEnforcementResult
@@ -107,6 +93,20 @@ Quota enforcement check result
10793
| **performance** | `{ usePartialIndexes: boolean; usePartitioning: boolean; poolSizePerTenant?: integer }` | optional | Performance settings |
10894

10995

96+
---
97+
98+
## SchemaLevelIsolationStrategy
99+
100+
### Properties
101+
102+
| Property | Type | Required | Description |
103+
| :--- | :--- | :--- | :--- |
104+
| **strategy** | `'isolated_schema'` || Schema-level isolation strategy |
105+
| **schema** | `{ namingPattern: string; includePublicSchema: boolean; sharedSchema: string; autoCreateSchema: boolean }` | optional | Schema configuration |
106+
| **migrations** | `{ strategy: Enum<'parallel' \| 'sequential' \| 'on_demand'>; maxConcurrent: integer; rollbackOnError: boolean }` | optional | Migration configuration |
107+
| **performance** | `{ poolPerSchema: boolean; schemaCacheTTL: integer }` | optional | Performance settings |
108+
109+
110110
---
111111

112112
## Tenant

packages/spec/authorable-surface.json

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3264,16 +3264,16 @@
32643264
"data/Document:tags",
32653265
"data/Document:template",
32663266
"data/Document:versioning",
3267+
"data/DocumentSchemaValidation:enabled",
3268+
"data/DocumentSchemaValidation:jsonSchema",
3269+
"data/DocumentSchemaValidation:validationAction",
3270+
"data/DocumentSchemaValidation:validationLevel",
32673271
"data/DocumentTemplate:description",
32683272
"data/DocumentTemplate:fileType",
32693273
"data/DocumentTemplate:fileUrl",
32703274
"data/DocumentTemplate:id",
32713275
"data/DocumentTemplate:name",
32723276
"data/DocumentTemplate:placeholders",
3273-
"data/DocumentValidationSchema:enabled",
3274-
"data/DocumentValidationSchema:jsonSchema",
3275-
"data/DocumentValidationSchema:validationAction",
3276-
"data/DocumentValidationSchema:validationLevel",
32773277
"data/DocumentVersion:checksum",
32783278
"data/DocumentVersion:createdAt",
32793279
"data/DocumentVersion:createdBy",
@@ -5798,12 +5798,6 @@
57985798
"system/ChangeRequest:status",
57995799
"system/ChangeRequest:title",
58005800
"system/ChangeRequest:type",
5801-
"system/ChangeSchema:changeType",
5802-
"system/ChangeSchema:entityName",
5803-
"system/ChangeSchema:entityType",
5804-
"system/ChangeSchema:newValue",
5805-
"system/ChangeSchema:oldValue",
5806-
"system/ChangeSchema:parentEntity",
58075801
"system/ChangeSet:author",
58085802
"system/ChangeSet:createdAt",
58095803
"system/ChangeSet:dependencies",
@@ -6206,10 +6200,6 @@
62066200
"system/LWWRegister:type",
62076201
"system/LWWRegister:value",
62086202
"system/LWWRegister:vectorClock",
6209-
"system/LevelIsolationStrategySchema:migrations",
6210-
"system/LevelIsolationStrategySchema:performance",
6211-
"system/LevelIsolationStrategySchema:schema",
6212-
"system/LevelIsolationStrategySchema:strategy",
62136203
"system/License:customFeatures",
62146204
"system/License:customLimits",
62156205
"system/License:expiresAt",
@@ -6664,6 +6654,16 @@
66646654
"system/SMSTemplate:maxLength",
66656655
"system/SMSTemplate:message",
66666656
"system/SMSTemplate:variables",
6657+
"system/SchemaChange:changeType",
6658+
"system/SchemaChange:entityName",
6659+
"system/SchemaChange:entityType",
6660+
"system/SchemaChange:newValue",
6661+
"system/SchemaChange:oldValue",
6662+
"system/SchemaChange:parentEntity",
6663+
"system/SchemaLevelIsolationStrategy:migrations",
6664+
"system/SchemaLevelIsolationStrategy:performance",
6665+
"system/SchemaLevelIsolationStrategy:schema",
6666+
"system/SchemaLevelIsolationStrategy:strategy",
66676667
"system/SearchConfig:analyzers",
66686668
"system/SearchConfig:facets",
66696669
"system/SearchConfig:indexes",

packages/spec/docs-import-surface.baseline.json

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@
4545
"data/DateGranularity — no type export",
4646
"data/DateMacroPlaceholder — no type export",
4747
"data/DimensionType — no type export",
48-
"data/DocumentValidationSchema — no schema const export",
49-
"data/DocumentValidationSchema — no type export",
5048
"data/DriverSslToggle — no type export",
5149
"data/DriverType — no type export",
5250
"data/EqualityOperator — no type export",
@@ -57,8 +55,6 @@
5755
"data/Index — no type export",
5856
"data/InstantValue — no type export",
5957
"data/LocationValue — no type export",
60-
"data/ModeSchema — no schema const export",
61-
"data/ModeSchema — no type export",
6258
"data/Object — no type export",
6359
"data/ObjectOwnershipEnum — no type export",
6460
"data/Query — no type export",
@@ -95,17 +91,13 @@
9591
"studio/ActivationEvent — no type export",
9692
"studio/PanelLocation — no type export",
9793
"system/AddFieldOperation — no type export",
98-
"system/ChangeSchema — no schema const export",
99-
"system/ChangeSchema — no type export",
10094
"system/CreateObjectOperation — no type export",
10195
"system/DeleteObjectOperation — no type export",
10296
"system/DeployStatusEnum — no type export",
10397
"system/EnvironmentArtifactFunctionLanguageEnum — no type export",
10498
"system/EnvironmentArtifactHashAlgorithmEnum — no type export",
10599
"system/ExecuteSqlOperation — no type export",
106100
"system/KernelServiceMap — no type export",
107-
"system/LevelIsolationStrategySchema — no schema const export",
108-
"system/LevelIsolationStrategySchema — no type export",
109101
"system/Locale — no type export",
110102
"system/MetadataState — no type export",
111103
"system/MigrationDependency — no type export",

packages/spec/json-schema.manifest.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"description": "Ratchet manifest of every JSON Schema emitted by scripts/build-schemas.ts. Auto-appended when new schemas are added (commit the change). A listed schema that a build no longer emits fails gen:schema \u2014 remove a key ONLY for a deliberate retirement. See #2978.",
2+
"description": "Ratchet manifest of every JSON Schema emitted by scripts/build-schemas.ts. Auto-appended when new schemas are added (commit the change). A listed schema that a build no longer emits fails gen:schema remove a key ONLY for a deliberate retirement. See #2978.",
33
"schemas": [
44
"ai/AIModelConfig",
55
"ai/AIUsageRecord",
@@ -724,8 +724,8 @@
724724
"data/Dimension",
725725
"data/DimensionType",
726726
"data/Document",
727+
"data/DocumentSchemaValidation",
727728
"data/DocumentTemplate",
728-
"data/DocumentValidationSchema",
729729
"data/DocumentVersion",
730730
"data/DriverCapabilities",
731731
"data/DriverConfig",
@@ -778,7 +778,6 @@
778778
"data/LocationValue",
779779
"data/Mapping",
780780
"data/Metric",
781-
"data/ModeSchema",
782781
"data/MongoConfig",
783782
"data/MysqlConfig",
784783
"data/NoSQLDataTypeMapping",
@@ -813,6 +812,7 @@
813812
"data/SQLDialect",
814813
"data/SQLDriverConfig",
815814
"data/SSLConfig",
815+
"data/SchemaMode",
816816
"data/ScriptBody",
817817
"data/ScriptValidation",
818818
"data/Seed",
@@ -1229,7 +1229,6 @@
12291229
"system/ChangeImpact",
12301230
"system/ChangePriority",
12311231
"system/ChangeRequest",
1232-
"system/ChangeSchema",
12331232
"system/ChangeSet",
12341233
"system/ChangeStatus",
12351234
"system/ChangeType",
@@ -1319,7 +1318,6 @@
13191318
"system/KeyManagementProvider",
13201319
"system/KeyRotationPolicy",
13211320
"system/LWWRegister",
1322-
"system/LevelIsolationStrategySchema",
13231321
"system/License",
13241322
"system/LicenseMetricType",
13251323
"system/LifecycleAction",
@@ -1415,6 +1413,8 @@
14151413
"system/SamplingDecision",
14161414
"system/SamplingStrategyType",
14171415
"system/Schedule",
1416+
"system/SchemaChange",
1417+
"system/SchemaLevelIsolationStrategy",
14181418
"system/SearchConfig",
14191419
"system/SearchIndexConfig",
14201420
"system/SearchProvider",

packages/spec/scripts/build-docs.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
type CategorySurface,
2828
} from './lib/docs-import-surface';
2929
import { createSink } from './lib/generated-output';
30+
import { schemaNameFromExportKey } from './lib/schema-name';
3031

3132
const SCHEMA_DIR = path.resolve(__dirname, '../json-schema');
3233
const SRC_DIR = path.resolve(__dirname, '../src');
@@ -130,7 +131,8 @@ function scanCategories() {
130131
let match;
131132
while ((match = regex.exec(content)) !== null) {
132133
const rawName = match[1];
133-
const finalName = rawName.endsWith('Schema') ? rawName.replace('Schema', '') : rawName;
134+
// Suffix-only strip — shared with build-schemas.ts; see lib/schema-name.ts (#4592).
135+
const finalName = schemaNameFromExportKey(rawName);
134136
schemaCategoryMap.set(finalName, category);
135137
schemaZodFileMap.set(finalName, slug);
136138
}

packages/spec/scripts/build-schemas.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ process.env.OS_EAGER_SCHEMAS = '1';
88
import fs from 'fs';
99
import path from 'path';
1010
import { z } from 'zod';
11+
import { schemaNameFromExportKey } from './lib/schema-name';
1112
import { CONVERSIONS_BY_MAJOR } from '../src/conversions/registry';
1213
import { MIGRATIONS_BY_MAJOR } from '../src/migrations/registry';
1314
import * as AI from '../src/ai';
@@ -197,7 +198,8 @@ for (const [namespaceName, namespaceExports] of Object.entries(Protocol)) {
197198
for (const [key, value] of Object.entries(namespaceExports)) {
198199
// Check if it looks like a Zod Schema
199200
if (value instanceof z.ZodType) {
200-
const schemaName = key.endsWith('Schema') ? key.replace('Schema', '') : key;
201+
// Suffix-only strip — shared with build-docs.ts; see lib/schema-name.ts (#4592).
202+
const schemaName = schemaNameFromExportKey(key);
201203

202204
try {
203205
// Convert to JSON Schema using Zod v4's built-in toJSONSchema().

0 commit comments

Comments
 (0)