@contember/bindx-generator 0.1.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.
Files changed (46) hide show
  1. package/README.md +258 -0
  2. package/dist/BindxGenerator.d.ts +41 -0
  3. package/dist/BindxGenerator.d.ts.map +1 -0
  4. package/dist/BindxGenerator.js +124 -0
  5. package/dist/BindxGenerator.js.map +1 -0
  6. package/dist/EntityTypeSchemaGenerator.d.ts +13 -0
  7. package/dist/EntityTypeSchemaGenerator.d.ts.map +1 -0
  8. package/dist/EntityTypeSchemaGenerator.js +64 -0
  9. package/dist/EntityTypeSchemaGenerator.js.map +1 -0
  10. package/dist/EnumTypeSchemaGenerator.d.ts +9 -0
  11. package/dist/EnumTypeSchemaGenerator.d.ts.map +1 -0
  12. package/dist/EnumTypeSchemaGenerator.js +19 -0
  13. package/dist/EnumTypeSchemaGenerator.js.map +1 -0
  14. package/dist/NameSchemaGenerator.d.ts +34 -0
  15. package/dist/NameSchemaGenerator.d.ts.map +1 -0
  16. package/dist/NameSchemaGenerator.js +39 -0
  17. package/dist/NameSchemaGenerator.js.map +1 -0
  18. package/dist/RoleNameSchemaGenerator.d.ts +24 -0
  19. package/dist/RoleNameSchemaGenerator.d.ts.map +1 -0
  20. package/dist/RoleNameSchemaGenerator.js +194 -0
  21. package/dist/RoleNameSchemaGenerator.js.map +1 -0
  22. package/dist/RoleSchemaGenerator.d.ts +41 -0
  23. package/dist/RoleSchemaGenerator.d.ts.map +1 -0
  24. package/dist/RoleSchemaGenerator.js +169 -0
  25. package/dist/RoleSchemaGenerator.js.map +1 -0
  26. package/dist/generate.d.ts +12 -0
  27. package/dist/generate.d.ts.map +1 -0
  28. package/dist/generate.js +45 -0
  29. package/dist/generate.js.map +1 -0
  30. package/dist/index.d.ts +17 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +14 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/utils.d.ts +17 -0
  35. package/dist/utils.d.ts.map +1 -0
  36. package/dist/utils.js +51 -0
  37. package/dist/utils.js.map +1 -0
  38. package/package.json +31 -0
  39. package/src/BindxGenerator.ts +154 -0
  40. package/src/EntityTypeSchemaGenerator.ts +77 -0
  41. package/src/EnumTypeSchemaGenerator.ts +24 -0
  42. package/src/NameSchemaGenerator.ts +66 -0
  43. package/src/RoleSchemaGenerator.ts +219 -0
  44. package/src/generate.ts +55 -0
  45. package/src/index.ts +19 -0
  46. package/src/utils.ts +54 -0
package/README.md ADDED
@@ -0,0 +1,258 @@
1
+ # @contember/bindx-generator
2
+
3
+ Schema generator for `@contember/bindx` with role-based ACL support. Generates TypeScript types and runtime schema definitions from Contember `Model.Schema` and `Acl.Schema`.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @contember/bindx-generator @contember/schema @contember/schema-utils
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Basic Generation (Without ACL)
14
+
15
+ ```typescript
16
+ import { generate } from '@contember/bindx-generator'
17
+ import { Model } from '@contember/schema'
18
+
19
+ const model: Model.Schema = {
20
+ enums: { /* ... */ },
21
+ entities: { /* ... */ }
22
+ }
23
+
24
+ const files = generate(model)
25
+
26
+ // Write files
27
+ for (const [filename, content] of Object.entries(files)) {
28
+ fs.writeFileSync(`./generated/${filename}`, content)
29
+ }
30
+ ```
31
+
32
+ ### Generation with Role-Based ACL
33
+
34
+ ```typescript
35
+ import { generate } from '@contember/bindx-generator'
36
+ import { Model, Acl } from '@contember/schema'
37
+
38
+ const model: Model.Schema = { /* ... */ }
39
+ const acl: Acl.Schema = {
40
+ roles: {
41
+ public: {
42
+ stages: '*',
43
+ entities: {
44
+ Article: {
45
+ predicates: {},
46
+ operations: {
47
+ read: {
48
+ id: true,
49
+ title: true,
50
+ // Only public fields
51
+ }
52
+ }
53
+ }
54
+ },
55
+ variables: {}
56
+ },
57
+ editor: {
58
+ stages: '*',
59
+ entities: {
60
+ Article: {
61
+ predicates: {},
62
+ operations: {
63
+ read: {
64
+ id: true,
65
+ title: true,
66
+ content: true,
67
+ author: true,
68
+ // All fields accessible to editors
69
+ }
70
+ }
71
+ }
72
+ },
73
+ variables: {}
74
+ }
75
+ }
76
+ }
77
+
78
+ const files = generate(model, acl)
79
+ ```
80
+
81
+ ## Generated Files
82
+
83
+ The generator produces 5 files:
84
+
85
+ | File | Description |
86
+ |------|-------------|
87
+ | `entities.ts` | TypeScript entity types with `columns`, `hasOne`, `hasMany` structure |
88
+ | `names.ts` | Runtime schema names (JSON) for query building |
89
+ | `enums.ts` | TypeScript enum types |
90
+ | `types.ts` | Shared schema interface definitions |
91
+ | `index.ts` | Exports and pre-configured bindx instance |
92
+
93
+ ### Example Output
94
+
95
+ #### Without ACL
96
+
97
+ ```typescript
98
+ // entities.ts
99
+ export interface Article {
100
+ columns: {
101
+ id: string
102
+ title: string
103
+ content: string | null
104
+ }
105
+ hasOne: {
106
+ author: Author
107
+ }
108
+ hasMany: {
109
+ tags: Tag
110
+ }
111
+ }
112
+
113
+ // index.ts
114
+ export const { useEntity, useEntityList, Entity, createComponent } = createBindx<BindxSchema>(schemaNames)
115
+ ```
116
+
117
+ #### With Role-Based ACL
118
+
119
+ ```typescript
120
+ // entities.ts
121
+ export interface PublicArticle {
122
+ columns: {
123
+ id: string
124
+ title: string
125
+ }
126
+ hasOne: {}
127
+ hasMany: {}
128
+ }
129
+
130
+ export interface EditorArticle {
131
+ columns: {
132
+ id: string
133
+ title: string
134
+ content: string | null
135
+ }
136
+ hasOne: {
137
+ author: EditorAuthor
138
+ }
139
+ hasMany: {
140
+ tags: EditorTag
141
+ }
142
+ }
143
+
144
+ export interface RoleSchemas {
145
+ public: PublicSchema
146
+ editor: EditorSchema
147
+ }
148
+
149
+ // index.ts
150
+ export const {
151
+ roleSchemaRegistry,
152
+ RoleAwareProvider,
153
+ Entity,
154
+ HasRole,
155
+ useEntity,
156
+ useEntityList,
157
+ createComponent
158
+ } = createRoleAwareBindx<RoleSchemas>(roleSchemaDefinitions)
159
+ ```
160
+
161
+ ## Options
162
+
163
+ ```typescript
164
+ export interface BindxGeneratorOptions {
165
+ /**
166
+ * Whether to flatten inherited roles.
167
+ * Default: true
168
+ */
169
+ flattenInheritance?: boolean
170
+
171
+ /**
172
+ * Whether to treat predicate-based permissions as allowed.
173
+ * When true, any non-false permission allows access.
174
+ * When false, only explicit `true` permissions are allowed.
175
+ * Default: true
176
+ */
177
+ allowPredicateAccess?: boolean
178
+ }
179
+
180
+ const files = generate(model, acl, {
181
+ flattenInheritance: true,
182
+ allowPredicateAccess: true
183
+ })
184
+ ```
185
+
186
+ ## CLI Usage
187
+
188
+ You can create a script to generate schemas:
189
+
190
+ ```typescript
191
+ // scripts/generate-schema.ts
192
+ import { generate } from '@contember/bindx-generator'
193
+ import { Model, Acl } from '@contember/schema'
194
+ import { writeFile, mkdir } from 'fs/promises'
195
+ import { join } from 'path'
196
+
197
+ // Import your model and ACL
198
+ import { model, acl } from './your-schema'
199
+
200
+ async function main() {
201
+ const files = generate(model, acl)
202
+
203
+ const outputDir = './src/generated'
204
+ await mkdir(outputDir, { recursive: true })
205
+
206
+ for (const [filename, content] of Object.entries(files)) {
207
+ await writeFile(join(outputDir, filename), content)
208
+ }
209
+
210
+ console.log('✅ Schema generated')
211
+ }
212
+
213
+ main()
214
+ ```
215
+
216
+ Add to `package.json`:
217
+
218
+ ```json
219
+ {
220
+ "scripts": {
221
+ "generate:schema": "tsx scripts/generate-schema.ts"
222
+ }
223
+ }
224
+ ```
225
+
226
+ ## How It Works
227
+
228
+ ### ACL Filtering
229
+
230
+ The generator applies ACL permissions similar to Contember's `IntrospectionSchemaFactory`:
231
+
232
+ 1. **Entity Filtering**: Only entities with `read` operations are included
233
+ 2. **Field Filtering**: Only fields with read permissions (`true` or predicates) are included
234
+ 3. **Relation Filtering**: Relations to inaccessible entities are excluded
235
+ 4. **Role Inheritance**: Permissions from inherited roles are merged
236
+
237
+ ### Type Safety
238
+
239
+ Generated types are fully type-safe:
240
+
241
+ ```typescript
242
+ // Public role cannot access content field
243
+ <RoleAwareProvider roles={['public']}>
244
+ <Entity name="Article" id={id}>
245
+ {article => (
246
+ // ✅ OK
247
+ <div>{article.data.title}</div>
248
+
249
+ // ❌ Type error: 'content' doesn't exist on PublicArticle
250
+ <div>{article.data.content}</div>
251
+ )}
252
+ </Entity>
253
+ </RoleAwareProvider>
254
+ ```
255
+
256
+ ## License
257
+
258
+ MIT
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Main bindx schema generator
3
+ *
4
+ * Generates TypeScript schema files from Contember Model.Schema.
5
+ */
6
+ import { Model, Acl } from '@contember/schema';
7
+ import { type RoleSchemaGeneratorOptions } from './RoleSchemaGenerator';
8
+ export interface BindxGeneratorOptions extends RoleSchemaGeneratorOptions {
9
+ }
10
+ export interface GeneratedFiles {
11
+ 'entities.ts': string;
12
+ 'names.ts'?: string;
13
+ 'enums.ts': string;
14
+ 'types.ts': string;
15
+ 'schema.ts': string;
16
+ 'index.ts': string;
17
+ }
18
+ export declare class BindxGenerator {
19
+ private readonly options;
20
+ private readonly entityTypeSchemaGenerator;
21
+ private readonly enumTypeSchemaGenerator;
22
+ private readonly nameSchemaGenerator;
23
+ private readonly roleSchemaGenerator;
24
+ constructor(options?: BindxGeneratorOptions);
25
+ /**
26
+ * Generate schema files
27
+ */
28
+ generate(model: Model.Schema, acl?: Acl.Schema): GeneratedFiles;
29
+ private generateSchemaFile;
30
+ private generateTypesFile;
31
+ }
32
+ /**
33
+ * Generate bindx schema files from Contember model
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * const files = generate(model)
38
+ * ```
39
+ */
40
+ export declare function generate(model: Model.Schema, aclOrOptions?: Acl.Schema | BindxGeneratorOptions, options?: BindxGeneratorOptions): GeneratedFiles;
41
+ //# sourceMappingURL=BindxGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BindxGenerator.d.ts","sourceRoot":"","sources":["../src/BindxGenerator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AAI9C,OAAO,EAAuB,KAAK,0BAA0B,EAAE,MAAM,uBAAuB,CAAA;AAE5F,MAAM,WAAW,qBAAsB,SAAQ,0BAA0B;CAExE;AAED,MAAM,WAAW,cAAc;IAC9B,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;CAClB;AAED,qBAAa,cAAc;IAMd,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAA2B;IACrE,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAyB;IACjE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;gBAE5B,OAAO,GAAE,qBAA0B;IAOhE;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,cAAc;IAqC/D,OAAO,CAAC,kBAAkB;IAqB1B,OAAO,CAAC,iBAAiB;CA0BzB;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACvB,KAAK,EAAE,KAAK,CAAC,MAAM,EACnB,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,qBAAqB,EACjD,OAAO,CAAC,EAAE,qBAAqB,GAC7B,cAAc,CAchB"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Main bindx schema generator
3
+ *
4
+ * Generates TypeScript schema files from Contember Model.Schema.
5
+ */
6
+ import { EntityTypeSchemaGenerator } from './EntityTypeSchemaGenerator';
7
+ import { EnumTypeSchemaGenerator } from './EnumTypeSchemaGenerator';
8
+ import { NameSchemaGenerator } from './NameSchemaGenerator';
9
+ import { RoleSchemaGenerator } from './RoleSchemaGenerator';
10
+ export class BindxGenerator {
11
+ options;
12
+ entityTypeSchemaGenerator;
13
+ enumTypeSchemaGenerator;
14
+ nameSchemaGenerator;
15
+ roleSchemaGenerator;
16
+ constructor(options = {}) {
17
+ this.options = options;
18
+ this.entityTypeSchemaGenerator = new EntityTypeSchemaGenerator();
19
+ this.enumTypeSchemaGenerator = new EnumTypeSchemaGenerator();
20
+ this.nameSchemaGenerator = new NameSchemaGenerator();
21
+ this.roleSchemaGenerator = new RoleSchemaGenerator(options);
22
+ }
23
+ /**
24
+ * Generate schema files
25
+ */
26
+ generate(model, acl) {
27
+ const enumsCode = this.enumTypeSchemaGenerator.generate(model);
28
+ let entitiesCode = this.entityTypeSchemaGenerator.generate(model);
29
+ const namesSchema = this.nameSchemaGenerator.generate(model);
30
+ // Append per-role entity types if ACL is provided
31
+ if (acl) {
32
+ entitiesCode += '\n' + this.roleSchemaGenerator.generateRoleEntities(model, acl);
33
+ }
34
+ const namesCode = `import type { BindxSchemaNames } from './types'
35
+
36
+ export const schemaNames: BindxSchemaNames = ${JSON.stringify(namesSchema, null, '\t')}
37
+ `;
38
+ const typesCode = this.generateTypesFile();
39
+ const schemaCode = acl
40
+ ? this.roleSchemaGenerator.generateSchemaFile(model, acl)
41
+ : this.generateSchemaFile(model);
42
+ const indexCode = `export * from './enums'
43
+ export * from './entities'
44
+ export * from './names'
45
+ export * from './types'
46
+ export * from './schema'
47
+ `;
48
+ return {
49
+ 'entities.ts': entitiesCode,
50
+ 'names.ts': namesCode,
51
+ 'enums.ts': enumsCode,
52
+ 'types.ts': typesCode,
53
+ 'schema.ts': schemaCode,
54
+ 'index.ts': indexCode,
55
+ };
56
+ }
57
+ generateSchemaFile(model) {
58
+ const entityNames = Object.values(model.entities).map(e => e.name).sort();
59
+ const imports = entityNames.join(', ');
60
+ const entries = entityNames
61
+ .map(name => `\t${name}: entityDef<${name}>('${name}', schemaDef),`)
62
+ .join('\n');
63
+ return `import { entityDef } from '@contember/bindx'
64
+ import { schemaNamesToDef } from '@contember/bindx-react'
65
+ import type { ${imports} } from './entities'
66
+ import { schemaNames } from './names'
67
+
68
+ const schemaDef = schemaNamesToDef(schemaNames)
69
+
70
+ export const schema = {
71
+ ${entries}
72
+ } as const
73
+ `;
74
+ }
75
+ generateTypesFile() {
76
+ return `/**
77
+ * Shared types for bindx schema
78
+ */
79
+
80
+ export interface BindxSchemaEntityNames {
81
+ readonly name: string
82
+ readonly scalars: readonly string[]
83
+ readonly fields: {
84
+ readonly [fieldName: string]:
85
+ | { readonly type: 'column'; readonly enumName?: string }
86
+ | { readonly type: 'one'; readonly entity: string }
87
+ | { readonly type: 'many'; readonly entity: string }
88
+ }
89
+ }
90
+
91
+ export interface BindxSchemaNames {
92
+ readonly entities: {
93
+ readonly [entityName: string]: BindxSchemaEntityNames
94
+ }
95
+ readonly enums: {
96
+ readonly [enumName: string]: readonly string[]
97
+ }
98
+ }
99
+ `;
100
+ }
101
+ }
102
+ /**
103
+ * Generate bindx schema files from Contember model
104
+ *
105
+ * @example
106
+ * ```ts
107
+ * const files = generate(model)
108
+ * ```
109
+ */
110
+ export function generate(model, aclOrOptions, options) {
111
+ // Support both generate(model, acl, options) and generate(model, options)
112
+ let acl;
113
+ let opts;
114
+ if (aclOrOptions && 'roles' in aclOrOptions) {
115
+ acl = aclOrOptions;
116
+ opts = options;
117
+ }
118
+ else {
119
+ opts = aclOrOptions;
120
+ }
121
+ const generator = new BindxGenerator(opts);
122
+ return generator.generate(model, acl);
123
+ }
124
+ //# sourceMappingURL=BindxGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BindxGenerator.js","sourceRoot":"","sources":["../src/BindxGenerator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Entity type schema generator for bindx
3
+ * Generates TypeScript entity types from Contember model
4
+ *
5
+ * Output format is designed to work with bindx's type system,
6
+ * separating columns, hasOne, and hasMany for proper type inference.
7
+ */
8
+ import { Model } from '@contember/schema';
9
+ export declare class EntityTypeSchemaGenerator {
10
+ generate(model: Model.Schema): string;
11
+ private generateEntityTypeCode;
12
+ }
13
+ //# sourceMappingURL=EntityTypeSchemaGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityTypeSchemaGenerator.d.ts","sourceRoot":"","sources":["../src/EntityTypeSchemaGenerator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAIzC,qBAAa,yBAAyB;IACrC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM;IAqCrC,OAAO,CAAC,sBAAsB;CA0B9B"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Entity type schema generator for bindx
3
+ * Generates TypeScript entity types from Contember model
4
+ *
5
+ * Output format is designed to work with bindx's type system,
6
+ * separating columns, hasOne, and hasMany for proper type inference.
7
+ */
8
+ import { acceptEveryFieldVisitor } from '@contember/schema-utils';
9
+ import { columnToTsType, getEnumTypeName } from './utils';
10
+ export class EntityTypeSchemaGenerator {
11
+ generate(model) {
12
+ let code = '';
13
+ // Import enum types
14
+ for (const enumName of Object.keys(model.enums)) {
15
+ code += `import type { ${getEnumTypeName(enumName)} } from './enums'\n`;
16
+ }
17
+ // Add JSON type definitions
18
+ code += `
19
+ export type JSONPrimitive = string | number | boolean | null
20
+ export type JSONValue = JSONPrimitive | JSONObject | JSONArray
21
+ export type JSONObject = { readonly [K in string]?: JSONValue }
22
+ export type JSONArray = readonly JSONValue[]
23
+
24
+ `;
25
+ // Generate entity types
26
+ for (const entity of Object.values(model.entities)) {
27
+ code += this.generateEntityTypeCode(model, entity);
28
+ }
29
+ // Generate schema type
30
+ code += '\n';
31
+ code += `export interface BindxEntities {\n`;
32
+ for (const entity of Object.values(model.entities)) {
33
+ code += `\t${entity.name}: ${entity.name}\n`;
34
+ }
35
+ code += '}\n\n';
36
+ code += `export interface BindxSchema {\n`;
37
+ code += '\tentities: BindxEntities\n';
38
+ code += '}\n';
39
+ return code;
40
+ }
41
+ generateEntityTypeCode(model, entity) {
42
+ let code = `export interface ${entity.name} {\n`;
43
+ let columnsCode = '';
44
+ let hasOneCode = '';
45
+ let hasManyCode = '';
46
+ acceptEveryFieldVisitor(model, entity, {
47
+ visitHasMany: ctx => {
48
+ hasManyCode += `\t\t${ctx.relation.name}: ${ctx.targetEntity.name}[]\n`;
49
+ },
50
+ visitHasOne: ctx => {
51
+ hasOneCode += `\t\t${ctx.relation.name}: ${ctx.targetEntity.name}\n`;
52
+ },
53
+ visitColumn: ctx => {
54
+ columnsCode += `\t\t${ctx.column.name}: ${columnToTsType(ctx.column)}${ctx.column.nullable ? ' | null' : ''}\n`;
55
+ },
56
+ });
57
+ code += columnsCode;
58
+ code += hasOneCode;
59
+ code += hasManyCode;
60
+ code += '}\n\n';
61
+ return code;
62
+ }
63
+ }
64
+ //# sourceMappingURL=EntityTypeSchemaGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityTypeSchemaGenerator.js","sourceRoot":"","sources":["../src/EntityTypeSchemaGenerator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAEzD,MAAM,OAAO,yBAAyB;IACrC,QAAQ,CAAC,KAAmB;QAC3B,IAAI,IAAI,GAAG,EAAE,CAAA;QAEb,oBAAoB;QACpB,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,IAAI,IAAI,iBAAiB,eAAe,CAAC,QAAQ,CAAC,qBAAqB,CAAA;QACxE,CAAC;QAED,4BAA4B;QAC5B,IAAI,IAAI;;;;;;CAMT,CAAA;QAEC,wBAAwB;QACxB,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,IAAI,IAAI,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACnD,CAAC;QAED,uBAAuB;QACvB,IAAI,IAAI,IAAI,CAAA;QACZ,IAAI,IAAI,oCAAoC,CAAA;QAC5C,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,IAAI,IAAI,KAAK,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI,CAAA;QAC7C,CAAC;QACD,IAAI,IAAI,OAAO,CAAA;QAEf,IAAI,IAAI,kCAAkC,CAAA;QAC1C,IAAI,IAAI,6BAA6B,CAAA;QACrC,IAAI,IAAI,KAAK,CAAA;QAEb,OAAO,IAAI,CAAA;IACZ,CAAC;IAEO,sBAAsB,CAAC,KAAmB,EAAE,MAAoB;QACvE,IAAI,IAAI,GAAG,oBAAoB,MAAM,CAAC,IAAI,MAAM,CAAA;QAEhD,IAAI,WAAW,GAAG,EAAE,CAAA;QACpB,IAAI,UAAU,GAAG,EAAE,CAAA;QACnB,IAAI,WAAW,GAAG,EAAE,CAAA;QAEpB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE;YACtC,YAAY,EAAE,GAAG,CAAC,EAAE;gBACnB,WAAW,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,CAAC,YAAY,CAAC,IAAI,MAAM,CAAA;YACxE,CAAC;YACD,WAAW,EAAE,GAAG,CAAC,EAAE;gBAClB,UAAU,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,CAAC,YAAY,CAAC,IAAI,IAAI,CAAA;YACrE,CAAC;YACD,WAAW,EAAE,GAAG,CAAC,EAAE;gBAClB,WAAW,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,CAAA;YAChH,CAAC;SACD,CAAC,CAAA;QAEF,IAAI,IAAI,WAAW,CAAA;QACnB,IAAI,IAAI,UAAU,CAAA;QAClB,IAAI,IAAI,WAAW,CAAA;QACnB,IAAI,IAAI,OAAO,CAAA;QAEf,OAAO,IAAI,CAAA;IACZ,CAAC;CACD"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Enum type schema generator for bindx
3
+ * Generates TypeScript enum types from Contember model enums
4
+ */
5
+ import { Model } from '@contember/schema';
6
+ export declare class EnumTypeSchemaGenerator {
7
+ generate(model: Model.Schema): string;
8
+ }
9
+ //# sourceMappingURL=EnumTypeSchemaGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnumTypeSchemaGenerator.d.ts","sourceRoot":"","sources":["../src/EnumTypeSchemaGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGzC,qBAAa,uBAAuB;IACnC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM;CAcrC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Enum type schema generator for bindx
3
+ * Generates TypeScript enum types from Contember model enums
4
+ */
5
+ import { getEnumTypeName } from './utils';
6
+ export class EnumTypeSchemaGenerator {
7
+ generate(model) {
8
+ let code = '';
9
+ for (const [enumName, values] of Object.entries(model.enums)) {
10
+ code += `export type ${getEnumTypeName(enumName)} = ${values.map(v => `'${v}'`).join(' | ')}\n\n`;
11
+ }
12
+ // Export enum values as const arrays for runtime use
13
+ for (const [enumName, values] of Object.entries(model.enums)) {
14
+ code += `export const ${enumName}Values = [${values.map(v => `'${v}'`).join(', ')}] as const\n`;
15
+ }
16
+ return code;
17
+ }
18
+ }
19
+ //# sourceMappingURL=EnumTypeSchemaGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnumTypeSchemaGenerator.js","sourceRoot":"","sources":["../src/EnumTypeSchemaGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAEzC,MAAM,OAAO,uBAAuB;IACnC,QAAQ,CAAC,KAAmB;QAC3B,IAAI,IAAI,GAAG,EAAE,CAAA;QAEb,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9D,IAAI,IAAI,eAAe,eAAe,CAAC,QAAQ,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAA;QAClG,CAAC;QAED,qDAAqD;QACrD,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9D,IAAI,IAAI,gBAAgB,QAAQ,aAAa,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAA;QAChG,CAAC;QAED,OAAO,IAAI,CAAA;IACZ,CAAC;CACD"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Name schema generator for bindx
3
+ * Generates runtime schema names (JSON structure) for query building
4
+ */
5
+ import { Model } from '@contember/schema';
6
+ export interface BindxSchemaEntityNames {
7
+ readonly name: string;
8
+ readonly scalars: readonly string[];
9
+ readonly fields: {
10
+ readonly [fieldName: string]: {
11
+ readonly type: 'column';
12
+ readonly columnType?: string;
13
+ readonly enumName?: string;
14
+ } | {
15
+ readonly type: 'one';
16
+ readonly entity: string;
17
+ } | {
18
+ readonly type: 'many';
19
+ readonly entity: string;
20
+ };
21
+ };
22
+ }
23
+ export interface BindxSchemaNames {
24
+ readonly entities: {
25
+ readonly [entityName: string]: BindxSchemaEntityNames;
26
+ };
27
+ readonly enums: {
28
+ readonly [enumName: string]: readonly string[];
29
+ };
30
+ }
31
+ export declare class NameSchemaGenerator {
32
+ generate(model: Model.Schema): BindxSchemaNames;
33
+ }
34
+ //# sourceMappingURL=NameSchemaGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NameSchemaGenerator.d.ts","sourceRoot":"","sources":["../src/NameSchemaGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGzC,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,QAAQ,CAAC,MAAM,EAAE;QAChB,QAAQ,EAAE,SAAS,EAAE,MAAM,GACxB;YAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;YAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,GACrF;YAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GACjD;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;KACrD,CAAA;CACD;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,QAAQ,EAAE;QAClB,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,sBAAsB,CAAA;KACrD,CAAA;IACD,QAAQ,CAAC,KAAK,EAAE;QACf,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAA;KAC9C,CAAA;CACD;AAED,qBAAa,mBAAmB;IAC/B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,gBAAgB;CAoC/C"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Name schema generator for bindx
3
+ * Generates runtime schema names (JSON structure) for query building
4
+ */
5
+ import { Model } from '@contember/schema';
6
+ import { acceptEveryFieldVisitor } from '@contember/schema-utils';
7
+ export class NameSchemaGenerator {
8
+ generate(model) {
9
+ return {
10
+ entities: Object.fromEntries(Object.values(model.entities).map(entity => {
11
+ const fields = {};
12
+ const scalars = [];
13
+ acceptEveryFieldVisitor(model, entity, {
14
+ visitHasOne: ctx => {
15
+ fields[ctx.relation.name] = {
16
+ type: 'one',
17
+ entity: ctx.targetEntity.name,
18
+ };
19
+ },
20
+ visitHasMany: ctx => {
21
+ fields[ctx.relation.name] = {
22
+ type: 'many',
23
+ entity: ctx.targetEntity.name,
24
+ };
25
+ },
26
+ visitColumn: ctx => {
27
+ scalars.push(ctx.column.name);
28
+ fields[ctx.column.name] = ctx.column.type === Model.ColumnType.Enum
29
+ ? { type: 'column', columnType: ctx.column.columnType, enumName: ctx.column.columnType }
30
+ : { type: 'column', columnType: ctx.column.columnType };
31
+ },
32
+ });
33
+ return [entity.name, { name: entity.name, fields, scalars }];
34
+ })),
35
+ enums: Object.fromEntries(Object.entries(model.enums).map(([name, values]) => [name, values])),
36
+ };
37
+ }
38
+ }
39
+ //# sourceMappingURL=NameSchemaGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NameSchemaGenerator.js","sourceRoot":"","sources":["../src/NameSchemaGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AAsBjE,MAAM,OAAO,mBAAmB;IAC/B,QAAQ,CAAC,KAAmB;QAC3B,OAAO;YACN,QAAQ,EAAE,MAAM,CAAC,WAAW,CAC3B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;gBAC1C,MAAM,MAAM,GAA6D,EAAE,CAAA;gBAC3E,MAAM,OAAO,GAAa,EAAE,CAAA;gBAE5B,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE;oBACtC,WAAW,EAAE,GAAG,CAAC,EAAE;wBAClB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG;4BAC3B,IAAI,EAAE,KAAK;4BACX,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,IAAI;yBAC7B,CAAA;oBACF,CAAC;oBACD,YAAY,EAAE,GAAG,CAAC,EAAE;wBACnB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG;4BAC3B,IAAI,EAAE,MAAM;4BACZ,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,IAAI;yBAC7B,CAAA;oBACF,CAAC;oBACD,WAAW,EAAE,GAAG,CAAC,EAAE;wBAClB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;wBAC7B,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,UAAU,CAAC,IAAI;4BAClE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE;4BACxF,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,CAAA;oBACzD,CAAC;iBACD,CAAC,CAAA;gBAEF,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;YAC7D,CAAC,CAAC,CACF;YACD,KAAK,EAAE,MAAM,CAAC,WAAW,CACxB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CACnE;SACD,CAAA;IACF,CAAC;CACD"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Role-aware name schema generator for bindx
3
+ * Generates runtime schema names filtered by ACL permissions per role
4
+ */
5
+ import { Acl, Model } from '@contember/schema';
6
+ import { BindxSchemaNames } from './NameSchemaGenerator';
7
+ export interface RoleSchemaNames {
8
+ readonly [roleName: string]: BindxSchemaNames;
9
+ }
10
+ export interface RoleNameSchemaGeneratorOptions {
11
+ flattenInheritance?: boolean;
12
+ allowPredicateAccess?: boolean;
13
+ }
14
+ export declare class RoleNameSchemaGenerator {
15
+ private options;
16
+ constructor(options?: RoleNameSchemaGeneratorOptions);
17
+ generate(model: Model.Schema, acl: Acl.Schema): RoleSchemaNames;
18
+ private generateForRole;
19
+ /**
20
+ * Generate TypeScript code that exports the role schema names
21
+ */
22
+ generateCode(model: Model.Schema, acl: Acl.Schema): string;
23
+ }
24
+ //# sourceMappingURL=RoleNameSchemaGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoleNameSchemaGenerator.d.ts","sourceRoot":"","sources":["../src/RoleNameSchemaGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAA0B,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAGhF,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAAA;CAC7C;AA2FD,MAAM,WAAW,8BAA8B;IAC9C,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC9B;AAED,qBAAa,uBAAuB;IACnC,OAAO,CAAC,OAAO,CAA0C;gBAE7C,OAAO,GAAE,8BAAmC;IAOxD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,eAAe;IAU/D,OAAO,CAAC,eAAe;IAmFvB;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM;CAqB1D"}