@fabricorg/gen-graphql 3.0.0 → 3.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.
- package/CHANGELOG.md +30 -0
- package/dist/index.cjs +5 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Release additive public compiler and generator APIs as minor versions. This includes parameterized
|
|
8
|
+
view schema contracts, the exported usage-contract JSON schema, and the runtime Platform validation
|
|
9
|
+
used by capability generation.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @fabricorg/compiler@2.2.0
|
|
15
|
+
|
|
16
|
+
## 3.0.1
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- b932767: Add portable parameter schemas and validation for projection views. Projection snapshot keys now
|
|
21
|
+
include a canonical parameter identity, generated capability and experience contracts preserve view
|
|
22
|
+
parameter schemas, and compatible snapshots continue through the explicit `upgradeSnapshot` seam.
|
|
23
|
+
- Updated dependencies [b932767]
|
|
24
|
+
- @fabricorg/compiler@2.1.1
|
|
25
|
+
|
|
26
|
+
### Additional release notes
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- Generate JSON parameters for parameterized projection query fields and pass them through the
|
|
31
|
+
ProjectionHost resolver seam.
|
|
32
|
+
|
|
3
33
|
## 3.0.0
|
|
4
34
|
|
|
5
35
|
### Major Changes
|
package/dist/index.cjs
CHANGED
|
@@ -153,7 +153,7 @@ ${fields.join("\n")}
|
|
|
153
153
|
}
|
|
154
154
|
var graphqlGenerator = {
|
|
155
155
|
name: "@fabricorg/gen-graphql",
|
|
156
|
-
version: "3.
|
|
156
|
+
version: "3.1.0",
|
|
157
157
|
generate(ir) {
|
|
158
158
|
return ir.modules.flatMap((module2) => {
|
|
159
159
|
const namespaceType = pascal(module2.namespace);
|
|
@@ -188,9 +188,9 @@ var graphqlGenerator = {
|
|
|
188
188
|
const rootName = `${pascal(view.name)}V${view.version.replace(/[^0-9A-Za-z]/g, "_")}`;
|
|
189
189
|
const projection = projectionFor(view.shape, rootName, `Module "${module2.namespace}" view "${view.name}@${view.version}" shape`);
|
|
190
190
|
const reference = project(view.shape, rootName, projection, "");
|
|
191
|
-
return { field: fieldName(view.name), reference, nonNull: !admitsNull(view.shape, projection) };
|
|
191
|
+
return { field: fieldName(view.name), reference, nonNull: !admitsNull(view.shape, projection), parameterized: Boolean(view.parameterSchema) };
|
|
192
192
|
});
|
|
193
|
-
const queryFields = viewPayloads.map((view) => ` ${view.field}: ${view.reference}${view.nonNull ? "!" : ""}`);
|
|
193
|
+
const queryFields = viewPayloads.map((view) => ` ${view.field}${view.parameterized ? "(parameters: JSON!)" : ""}: ${view.reference}${view.nonNull ? "!" : ""}`);
|
|
194
194
|
const mutations = module2.actions.map((action) => ` ${fieldName(action.actionId)}(parameters: JSON!): GovernedActionSubmission!`);
|
|
195
195
|
const operationNames = [...viewPayloads.map((view) => view.field), ...module2.actions.map((action) => fieldName(action.actionId))];
|
|
196
196
|
if (new Set(operationNames).size !== operationNames.length) throw new Error(`Module "${module2.namespace}" produces colliding GraphQL operation names.`);
|
|
@@ -240,8 +240,8 @@ ${mutations.length ? mutations.join("\n") : " _fabric: Boolean!"}
|
|
|
240
240
|
"export function createResolvers<TContext>(wiring: ResolverWiring<TContext>) {",
|
|
241
241
|
" return {",
|
|
242
242
|
" Query: {",
|
|
243
|
-
...
|
|
244
|
-
(field) => ` ${JSON.stringify(field)}: async (_parent: unknown, _args: unknown, context: TContext) => resolveProjection(wiring.projectionHost, ${JSON.stringify(field)}, await wiring.projectionContext(context)),`
|
|
243
|
+
...viewPayloads.map(
|
|
244
|
+
(view) => view.parameterized ? ` ${JSON.stringify(view.field)}: async (_parent: unknown, args: { parameters: unknown }, context: TContext) => resolveProjection(wiring.projectionHost, ${JSON.stringify(view.field)}, { ...await wiring.projectionContext(context), parameters: args.parameters }),` : ` ${JSON.stringify(view.field)}: async (_parent: unknown, _args: unknown, context: TContext) => resolveProjection(wiring.projectionHost, ${JSON.stringify(view.field)}, await wiring.projectionContext(context)),`
|
|
245
245
|
),
|
|
246
246
|
" },",
|
|
247
247
|
" Mutation: {",
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"sourcesContent":["import type { GeneratorTarget } from \"@fabricorg/compiler\";\nimport type { PortableJsonSchema } from \"@fabricorg/platform\";\n\nconst pascal = (value: string): string =>\n\tvalue.split(/[-._/]/).filter(Boolean).map((part) => part[0]?.toUpperCase() + part.slice(1)).join(\"\");\n\nconst identifier = (value: string): string => {\n\tconst normalized = value.replace(/[^_0-9A-Za-z]/g, \"_\");\n\treturn /^[_A-Za-z]/.test(normalized) ? normalized : `field_${normalized}`;\n};\n\nconst SCALARS: Record<string, string> = { string: \"String\", integer: \"Int\", number: \"Float\", boolean: \"Boolean\" };\n\n/**\n * Named SDL blocks discovered while projecting one document, plus the `$defs`\n * names already claimed so a recursive `$ref` resolves to the type being built\n * rather than recursing forever.\n */\ninterface Projection {\n\t/** Insertion-ordered so emitted SDL is deterministic for a given manifest. Empty value means reserved-but-unfilled. */\n\ttypes: Map<string, string>;\n\trefs: Map<string, string>;\n\t/** The whole document, so a `$ref` in any property resolves against its `$defs`. */\n\troot: PortableJsonSchema;\n\trootName: string;\n\tsubject: string;\n}\n\nfunction unsupported(projection: Projection, path: string, reason: string): never {\n\tthrow new Error(`${projection.subject}${path} ${reason}. Give the view or object an explicit GraphQL-projectable shape.`);\n}\n\n/** Take a unique type name before projecting children, so a recursive `$ref` back to this type resolves to the same name. */\nfunction reserve(projection: Projection, preferred: string): string {\n\tlet name = preferred;\n\tfor (let suffix = 2; projection.types.has(name); suffix += 1) name = `${preferred}${suffix}`;\n\tprojection.types.set(name, \"\");\n\treturn name;\n}\n\n/** Resolve `#/$defs/<key>` only; any other pointer is not portable across generators. */\nfunction resolveRef(projection: Projection, ref: string, path: string): { schema: PortableJsonSchema; key: string } {\n\tconst match = /^#\\/\\$defs\\/([^/]+)$/.exec(ref);\n\tif (!match) unsupported(projection, path, `uses $ref \"${ref}\", which is not a local \"#/$defs/<name>\" pointer`);\n\tconst key = decodeURIComponent(match[1]!.replace(/~1/g, \"/\").replace(/~0/g, \"~\"));\n\tconst target = projection.root.$defs?.[key];\n\tif (!target) unsupported(projection, path, `references missing definition \"#/$defs/${key}\"`);\n\treturn { schema: target, key };\n}\n\n/** A shape that becomes a named GraphQL object type rather than a scalar, list or JSON. */\nfunction isObjectShape(schema: PortableJsonSchema): boolean {\n\treturn schema.$ref === undefined\n\t\t&& (schema.type === undefined || schema.type === \"object\")\n\t\t&& !Array.isArray(schema.enum)\n\t\t&& Object.keys(schema.properties ?? {}).length > 0;\n}\n\n/**\n * Whether a value may legitimately be null, following local refs. GraphQL\n * non-null is a promise to the client, so a required field whose definition\n * admits null must still be nullable.\n */\nfunction admitsNull(schema: PortableJsonSchema, projection: Projection, seen: Set<string> = new Set()): boolean {\n\tif (schema.$ref !== undefined) {\n\t\tconst match = /^#\\/\\$defs\\/([^/]+)$/.exec(schema.$ref);\n\t\tif (!match) return false;\n\t\tconst key = decodeURIComponent(match[1]!.replace(/~1/g, \"/\").replace(/~0/g, \"~\"));\n\t\tif (seen.has(key)) return false;\n\t\tseen.add(key);\n\t\tconst target = projection.root.$defs?.[key];\n\t\treturn target ? admitsNull(target, projection, seen) : false;\n\t}\n\tif (Array.isArray(schema.type)) return schema.type.includes(\"null\");\n\tif (schema.type === \"null\") return true;\n\treturn Array.isArray(schema.enum) ? schema.enum.includes(null) : false;\n}\n\nfunction enumType(projection: Projection, schema: PortableJsonSchema, preferred: string): string | undefined {\n\tconst values = schema.enum;\n\tif (!Array.isArray(values) || values.length === 0) return undefined;\n\tconst members = values.filter((value) => value !== null);\n\tif (members.length === 0) return undefined;\n\tif (!members.every((value) => typeof value === \"string\" && /^[_A-Za-z][_0-9A-Za-z]*$/.test(value))) return undefined;\n\tconst unique = [...new Set(members as string[])];\n\tconst name = reserve(projection, preferred);\n\tprojection.types.set(name, `enum ${name} {\\n${unique.map((member) => ` ${member}`).join(\"\\n\")}\\n}`);\n\treturn name;\n}\n\n/** Returns a GraphQL type reference without nullability; callers append `!`. */\nfunction project(schema: PortableJsonSchema, preferred: string, projection: Projection, path: string): string {\n\tfor (const keyword of [\"oneOf\", \"anyOf\", \"allOf\", \"not\", \"if\"] as const) {\n\t\tif (schema[keyword] !== undefined) unsupported(projection, path, `uses \"${keyword}\", which has no GraphQL projection`);\n\t}\n\n\tif (schema.$ref !== undefined) {\n\t\tconst { schema: target, key } = resolveRef(projection, schema.$ref, path);\n\t\tconst claimed = projection.refs.get(key);\n\t\tif (claimed) return claimed;\n\t\tconst preferredRefName = `${projection.rootName}${pascal(key)}`;\n\t\tif (isObjectShape(target)) {\n\t\t\t// Reserve before projecting the definition's own fields, so a definition that\n\t\t\t// refers back to itself resolves to this very name and nothing is ever unbound.\n\t\t\tconst name = reserve(projection, preferredRefName);\n\t\t\tprojection.refs.set(key, name);\n\t\t\tprojection.types.set(name, objectSdl(name, Object.entries(target.properties ?? {}), target, projection, `${path} -> $defs.${key}`));\n\t\t\treturn name;\n\t\t}\n\t\tconst projected = project(target, preferredRefName, projection, `${path} -> $defs.${key}`);\n\t\tprojection.refs.set(key, projected);\n\t\treturn projected;\n\t}\n\n\tconst declared = Array.isArray(schema.type) ? schema.type.filter((entry) => entry !== \"null\") : schema.type === undefined ? [] : [schema.type];\n\tif (Array.isArray(schema.type) && declared.length > 1) {\n\t\tunsupported(projection, path, `declares the union type [${schema.type.join(\", \")}], which has no GraphQL projection`);\n\t}\n\tif (Array.isArray(schema.type) && declared.length === 0) {\n\t\tunsupported(projection, path, `declares only the null type, which has no GraphQL projection`);\n\t}\n\tconst type = declared[0];\n\tif (type === \"null\") unsupported(projection, path, `declares only the null type, which has no GraphQL projection`);\n\n\tif (type === undefined || type === \"object\") {\n\t\tconst named = enumType(projection, schema, preferred);\n\t\tif (named) return named;\n\t\tconst properties = Object.entries(schema.properties ?? {});\n\t\tif (properties.length === 0) {\n\t\t\t// A shape constrained to keys or values we cannot name is not \"anything\";\n\t\t\t// it is a map, and a map has no GraphQL projection.\n\t\t\tfor (const keyword of [\"patternProperties\", \"propertyNames\"] as const) {\n\t\t\t\tif (schema[keyword] !== undefined) unsupported(projection, path, `uses \"${keyword}\" with no declared properties, which has no GraphQL projection`);\n\t\t\t}\n\t\t\tif (schema.additionalProperties !== undefined && typeof schema.additionalProperties !== \"boolean\") {\n\t\t\t\tunsupported(projection, path, `constrains \"additionalProperties\" with no declared properties, which has no GraphQL projection`);\n\t\t\t}\n\t\t\t// Genuinely unconstrained: any JSON object is valid here.\n\t\t\treturn \"JSON\";\n\t\t}\n\t\tif (schema.patternProperties !== undefined) unsupported(projection, path, `uses \"patternProperties\" alongside \"properties\", which has no GraphQL projection`);\n\t\tconst name = reserve(projection, preferred);\n\t\tprojection.types.set(name, objectSdl(name, properties, schema, projection, path));\n\t\treturn name;\n\t}\n\n\tif (type === \"array\") {\n\t\tif (schema.prefixItems !== undefined) unsupported(projection, path, `uses \"prefixItems\", which has no GraphQL projection`);\n\t\tif (Array.isArray(schema.items)) unsupported(projection, path, `uses tuple \"items\", which has no GraphQL projection`);\n\t\t// A list whose element type is undeclared cannot be expressed as a GraphQL list.\n\t\tif (schema.items === undefined) unsupported(projection, path, `declares an array without \"items\", so its element type has no GraphQL projection`);\n\t\tconst item = schema.items;\n\t\tconst reference = project(item, `${preferred}Item`, projection, `${path}[]`);\n\t\treturn `[${reference}${admitsNull(item, projection) ? \"\" : \"!\"}]`;\n\t}\n\n\tconst named = enumType(projection, schema, preferred);\n\tif (named) return named;\n\tconst scalar = SCALARS[type];\n\tif (!scalar) unsupported(projection, path, `declares unsupported type \"${type}\"`);\n\treturn scalar;\n}\n\nfunction objectSdl(\n\tname: string,\n\tproperties: Array<[string, PortableJsonSchema]>,\n\tschema: PortableJsonSchema,\n\tprojection: Projection,\n\tpath: string,\n): string {\n\tconst required = new Set(schema.required ?? []);\n\tconst fieldNames = properties.map(([property]) => identifier(property));\n\tif (new Set(fieldNames).size !== fieldNames.length) {\n\t\tthrow new Error(`${projection.subject}${path} produces colliding GraphQL field names.`);\n\t}\n\tconst fields = properties.map(([property, child], index) => {\n\t\tconst reference = project(child, `${name}${pascal(property)}`, projection, `${path}.${property}`);\n\t\tconst nonNull = required.has(property) && !admitsNull(child, projection);\n\t\treturn ` ${fieldNames[index]}: ${reference}${nonNull ? \"!\" : \"\"}`;\n\t});\n\treturn `type ${name} {\\n${fields.join(\"\\n\")}\\n}`;\n}\n\nexport const graphqlGenerator: GeneratorTarget = {\n\tname: \"@fabricorg/gen-graphql\",\n\tversion: \"3.0.0\",\n\tgenerate(ir) {\n\t\treturn ir.modules.flatMap((module) => {\n\t\t\tconst namespaceType = pascal(module.namespace);\n\t\t\t// One registry per module: entity types, their nested types and every view\n\t\t\t// payload draw names from the same pool, so a collision is impossible rather\n\t\t\t// than merely unlikely.\n\t\t\tconst types = new Map<string, string>();\n\n\t\t\t// One projection per document, so a `$ref` in any property resolves against the\n\t\t\t// entity's own `$defs` rather than against that single property.\n\t\t\tconst projectionFor = (root: PortableJsonSchema, rootName: string, subject: string): Projection =>\n\t\t\t\t({ types, refs: new Map(), root, rootName, subject });\n\n\t\t\tfor (const objectType of module.objectTypes) {\n\t\t\t\tconst subject = `Module \"${module.namespace}\" object \"${objectType.type}\"`;\n\t\t\t\tconst schema = objectType.schema ?? {};\n\t\t\t\tconst required = new Set(schema.required ?? []);\n\t\t\t\tconst properties = Object.entries(schema.properties ?? {}).filter(([name]) => ![\"id\", \"tenantId\", \"spaceId\"].includes(name));\n\t\t\t\tconst fieldNames = properties.map(([name]) => identifier(name));\n\t\t\t\tif (new Set(fieldNames).size !== fieldNames.length) throw new Error(`Object \"${module.namespace}.${objectType.type}\" produces colliding GraphQL field names.`);\n\t\t\t\tconst entityName = `${namespaceType}${objectType.type}`;\n\t\t\t\tif (types.has(entityName)) throw new Error(`Module \"${module.namespace}\" produces two GraphQL types named \"${entityName}\".`);\n\t\t\t\ttypes.set(entityName, \"\");\n\t\t\t\tconst projection = projectionFor(schema, entityName, subject);\n\t\t\t\tfor (const keyword of [\"oneOf\", \"anyOf\", \"allOf\", \"not\", \"if\"] as const) {\n\t\t\t\t\tif (schema[keyword] !== undefined) unsupported(projection, \"\", `uses \"${keyword}\", which has no GraphQL projection`);\n\t\t\t\t}\n\t\t\t\tconst fields = properties.map(([name, child], index) => {\n\t\t\t\t\tconst reference = project(child, `${entityName}${pascal(name)}`, projection, `.${name}`);\n\t\t\t\t\tconst nonNull = required.has(name) && !admitsNull(child, projection);\n\t\t\t\t\treturn ` ${fieldNames[index]}: ${reference}${nonNull ? \"!\" : \"\"}`;\n\t\t\t\t});\n\t\t\t\ttypes.set(entityName, [`type ${entityName} @key(fields: \"id\") {`, \" id: ID!\", \" tenantId: ID!\", \" spaceId: ID!\", ...fields, \"}\"].join(\"\\n\"));\n\t\t\t}\n\n\t\t\tconst fieldName = (value: string): string => {\n\t\t\t\tconst name = pascal(value);\n\t\t\t\treturn `${name[0]?.toLowerCase() ?? \"\"}${name.slice(1)}`;\n\t\t\t};\n\n\t\t\tconst viewPayloads = module.views.map((view) => {\n\t\t\t\tconst rootName = `${pascal(view.name)}V${view.version.replace(/[^0-9A-Za-z]/g, \"_\")}`;\n\t\t\t\tconst projection = projectionFor(view.shape, rootName, `Module \"${module.namespace}\" view \"${view.name}@${view.version}\" shape`);\n\t\t\t\tconst reference = project(view.shape, rootName, projection, \"\");\n\t\t\t\treturn { field: fieldName(view.name), reference, nonNull: !admitsNull(view.shape, projection) };\n\t\t\t});\n\n\t\t\tconst queryFields = viewPayloads.map((view) => ` ${view.field}: ${view.reference}${view.nonNull ? \"!\" : \"\"}`);\n\t\t\tconst mutations = module.actions.map((action) => ` ${fieldName(action.actionId)}(parameters: JSON!): GovernedActionSubmission!`);\n\t\t\tconst operationNames = [...viewPayloads.map((view) => view.field), ...module.actions.map((action) => fieldName(action.actionId))];\n\t\t\tif (new Set(operationNames).size !== operationNames.length) throw new Error(`Module \"${module.namespace}\" produces colliding GraphQL operation names.`);\n\n\t\t\tconst content = [\n\t\t\t\t`# Generated by ${graphqlGenerator.name}@${graphqlGenerator.version}`,\n\t\t\t\t`# Manifest digest: ${ir.manifestDigest}`,\n\t\t\t\t'extend schema @link(url: \"https://specs.apollo.dev/federation/v2.7\", import: [\"@key\"])',\n\t\t\t\t\"scalar JSON\",\n\t\t\t\t\"type GovernedActionSubmission { actionInvocationId: ID!, status: String! }\",\n\t\t\t\t...[...types.values()].filter(Boolean),\n\t\t\t\t`type Query {\\n${queryFields.length ? queryFields.join(\"\\n\") : \" _fabric: Boolean!\"}\\n}`,\n\t\t\t\t`type Mutation {\\n${mutations.length ? mutations.join(\"\\n\") : \" _fabric: Boolean!\"}\\n}`,\n\t\t\t\t\"\",\n\t\t\t].join(\"\\n\\n\");\n\n\t\t\tconst actionIds = Object.fromEntries(module.actions.map((action) => [fieldName(action.actionId), action.actionId]));\n\t\t\tconst viewIds = Object.fromEntries(module.views.map((view) => [fieldName(view.name), { name: view.name, version: view.version }]));\n\n\t\t\tconst resolvers = [\n\t\t\t\t'import type { ProjectionHost, ProjectionQuery } from \"@fabricorg/projection-host\";',\n\t\t\t\t'import type { GovernedActionHost, SubmitActionInput, SubmitActionResult } from \"@fabricorg/platform-host\";',\n\t\t\t\t\"\",\n\t\t\t\t\"// Generated resolver seam. Authenticate first; derive actor and tenant server-side.\",\n\t\t\t\t`export const actionIds = ${JSON.stringify(actionIds, null, 2)} as const;`,\n\t\t\t\t`export const viewIds = ${JSON.stringify(viewIds, null, 2)} as const;`,\n\t\t\t\t\"\",\n\t\t\t\t'export async function resolveProjection(host: Pick<ProjectionHost, \"project\">, field: keyof typeof viewIds, context: Omit<ProjectionQuery, \"view\">): Promise<unknown> {',\n\t\t\t\t\" const result = await host.project({ ...context, view: viewIds[field] });\",\n\t\t\t\t\" return result.state;\",\n\t\t\t\t\"}\",\n\t\t\t\t'export type GovernedMutationContext = Omit<SubmitActionInput, \"actionId\" | \"parameters\">;',\n\t\t\t\t'export async function submitMutation(host: Pick<GovernedActionHost, \"submitAction\">, field: keyof typeof actionIds, parameters: Record<string, unknown>, context: GovernedMutationContext): Promise<SubmitActionResult> {',\n\t\t\t\t\" return await host.submitAction({ ...context, actionId: actionIds[field], parameters });\",\n\t\t\t\t\"}\",\n\t\t\t\t\"\",\n\t\t\t\t\"export interface ResolverWiring<TContext> {\",\n\t\t\t\t' projectionHost: Pick<ProjectionHost, \"project\">;',\n\t\t\t\t' actionHost: Pick<GovernedActionHost, \"submitAction\">;',\n\t\t\t\t\" /** Derive tenant, space and actor from the authenticated request. Never from client input. */\",\n\t\t\t\t' projectionContext: (context: TContext) => Omit<ProjectionQuery, \"view\"> | Promise<Omit<ProjectionQuery, \"view\">>;',\n\t\t\t\t\" mutationContext: (context: TContext) => GovernedMutationContext | Promise<GovernedMutationContext>;\",\n\t\t\t\t\"}\",\n\t\t\t\t\"\",\n\t\t\t\t\"/** Executable resolver map. Query fields read through ProjectionHost; Mutation fields submit through the governed Host. */\",\n\t\t\t\t\"export function createResolvers<TContext>(wiring: ResolverWiring<TContext>) {\",\n\t\t\t\t\" return {\",\n\t\t\t\t\" Query: {\",\n\t\t\t\t...Object.keys(viewIds).map((field) =>\n\t\t\t\t\t` ${JSON.stringify(field)}: async (_parent: unknown, _args: unknown, context: TContext) => resolveProjection(wiring.projectionHost, ${JSON.stringify(field)}, await wiring.projectionContext(context)),`,\n\t\t\t\t),\n\t\t\t\t\" },\",\n\t\t\t\t\" Mutation: {\",\n\t\t\t\t...Object.keys(actionIds).map((field) =>\n\t\t\t\t\t` ${JSON.stringify(field)}: async (_parent: unknown, args: { parameters: Record<string, unknown> }, context: TContext) => submitMutation(wiring.actionHost, ${JSON.stringify(field)}, args.parameters, await wiring.mutationContext(context)),`,\n\t\t\t\t),\n\t\t\t\t\" },\",\n\t\t\t\t\" };\",\n\t\t\t\t\"}\",\n\t\t\t\t\"\",\n\t\t\t].join(\"\\n\");\n\n\t\t\treturn [{ path: `${module.namespace}/schema.graphql`, content }, { path: `${module.namespace}/resolver-contract.ts`, content: resolvers }];\n\t\t});\n\t},\n};\n"],"mappings":"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","names":["named","module"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"sourcesContent":["import type { GeneratorTarget } from \"@fabricorg/compiler\";\nimport type { PortableJsonSchema } from \"@fabricorg/platform\";\n\nconst pascal = (value: string): string =>\n\tvalue.split(/[-._/]/).filter(Boolean).map((part) => part[0]?.toUpperCase() + part.slice(1)).join(\"\");\n\nconst identifier = (value: string): string => {\n\tconst normalized = value.replace(/[^_0-9A-Za-z]/g, \"_\");\n\treturn /^[_A-Za-z]/.test(normalized) ? normalized : `field_${normalized}`;\n};\n\nconst SCALARS: Record<string, string> = { string: \"String\", integer: \"Int\", number: \"Float\", boolean: \"Boolean\" };\n\n/**\n * Named SDL blocks discovered while projecting one document, plus the `$defs`\n * names already claimed so a recursive `$ref` resolves to the type being built\n * rather than recursing forever.\n */\ninterface Projection {\n\t/** Insertion-ordered so emitted SDL is deterministic for a given manifest. Empty value means reserved-but-unfilled. */\n\ttypes: Map<string, string>;\n\trefs: Map<string, string>;\n\t/** The whole document, so a `$ref` in any property resolves against its `$defs`. */\n\troot: PortableJsonSchema;\n\trootName: string;\n\tsubject: string;\n}\n\nfunction unsupported(projection: Projection, path: string, reason: string): never {\n\tthrow new Error(`${projection.subject}${path} ${reason}. Give the view or object an explicit GraphQL-projectable shape.`);\n}\n\n/** Take a unique type name before projecting children, so a recursive `$ref` back to this type resolves to the same name. */\nfunction reserve(projection: Projection, preferred: string): string {\n\tlet name = preferred;\n\tfor (let suffix = 2; projection.types.has(name); suffix += 1) name = `${preferred}${suffix}`;\n\tprojection.types.set(name, \"\");\n\treturn name;\n}\n\n/** Resolve `#/$defs/<key>` only; any other pointer is not portable across generators. */\nfunction resolveRef(projection: Projection, ref: string, path: string): { schema: PortableJsonSchema; key: string } {\n\tconst match = /^#\\/\\$defs\\/([^/]+)$/.exec(ref);\n\tif (!match) unsupported(projection, path, `uses $ref \"${ref}\", which is not a local \"#/$defs/<name>\" pointer`);\n\tconst key = decodeURIComponent(match[1]!.replace(/~1/g, \"/\").replace(/~0/g, \"~\"));\n\tconst target = projection.root.$defs?.[key];\n\tif (!target) unsupported(projection, path, `references missing definition \"#/$defs/${key}\"`);\n\treturn { schema: target, key };\n}\n\n/** A shape that becomes a named GraphQL object type rather than a scalar, list or JSON. */\nfunction isObjectShape(schema: PortableJsonSchema): boolean {\n\treturn schema.$ref === undefined\n\t\t&& (schema.type === undefined || schema.type === \"object\")\n\t\t&& !Array.isArray(schema.enum)\n\t\t&& Object.keys(schema.properties ?? {}).length > 0;\n}\n\n/**\n * Whether a value may legitimately be null, following local refs. GraphQL\n * non-null is a promise to the client, so a required field whose definition\n * admits null must still be nullable.\n */\nfunction admitsNull(schema: PortableJsonSchema, projection: Projection, seen: Set<string> = new Set()): boolean {\n\tif (schema.$ref !== undefined) {\n\t\tconst match = /^#\\/\\$defs\\/([^/]+)$/.exec(schema.$ref);\n\t\tif (!match) return false;\n\t\tconst key = decodeURIComponent(match[1]!.replace(/~1/g, \"/\").replace(/~0/g, \"~\"));\n\t\tif (seen.has(key)) return false;\n\t\tseen.add(key);\n\t\tconst target = projection.root.$defs?.[key];\n\t\treturn target ? admitsNull(target, projection, seen) : false;\n\t}\n\tif (Array.isArray(schema.type)) return schema.type.includes(\"null\");\n\tif (schema.type === \"null\") return true;\n\treturn Array.isArray(schema.enum) ? schema.enum.includes(null) : false;\n}\n\nfunction enumType(projection: Projection, schema: PortableJsonSchema, preferred: string): string | undefined {\n\tconst values = schema.enum;\n\tif (!Array.isArray(values) || values.length === 0) return undefined;\n\tconst members = values.filter((value) => value !== null);\n\tif (members.length === 0) return undefined;\n\tif (!members.every((value) => typeof value === \"string\" && /^[_A-Za-z][_0-9A-Za-z]*$/.test(value))) return undefined;\n\tconst unique = [...new Set(members as string[])];\n\tconst name = reserve(projection, preferred);\n\tprojection.types.set(name, `enum ${name} {\\n${unique.map((member) => ` ${member}`).join(\"\\n\")}\\n}`);\n\treturn name;\n}\n\n/** Returns a GraphQL type reference without nullability; callers append `!`. */\nfunction project(schema: PortableJsonSchema, preferred: string, projection: Projection, path: string): string {\n\tfor (const keyword of [\"oneOf\", \"anyOf\", \"allOf\", \"not\", \"if\"] as const) {\n\t\tif (schema[keyword] !== undefined) unsupported(projection, path, `uses \"${keyword}\", which has no GraphQL projection`);\n\t}\n\n\tif (schema.$ref !== undefined) {\n\t\tconst { schema: target, key } = resolveRef(projection, schema.$ref, path);\n\t\tconst claimed = projection.refs.get(key);\n\t\tif (claimed) return claimed;\n\t\tconst preferredRefName = `${projection.rootName}${pascal(key)}`;\n\t\tif (isObjectShape(target)) {\n\t\t\t// Reserve before projecting the definition's own fields, so a definition that\n\t\t\t// refers back to itself resolves to this very name and nothing is ever unbound.\n\t\t\tconst name = reserve(projection, preferredRefName);\n\t\t\tprojection.refs.set(key, name);\n\t\t\tprojection.types.set(name, objectSdl(name, Object.entries(target.properties ?? {}), target, projection, `${path} -> $defs.${key}`));\n\t\t\treturn name;\n\t\t}\n\t\tconst projected = project(target, preferredRefName, projection, `${path} -> $defs.${key}`);\n\t\tprojection.refs.set(key, projected);\n\t\treturn projected;\n\t}\n\n\tconst declared = Array.isArray(schema.type) ? schema.type.filter((entry) => entry !== \"null\") : schema.type === undefined ? [] : [schema.type];\n\tif (Array.isArray(schema.type) && declared.length > 1) {\n\t\tunsupported(projection, path, `declares the union type [${schema.type.join(\", \")}], which has no GraphQL projection`);\n\t}\n\tif (Array.isArray(schema.type) && declared.length === 0) {\n\t\tunsupported(projection, path, `declares only the null type, which has no GraphQL projection`);\n\t}\n\tconst type = declared[0];\n\tif (type === \"null\") unsupported(projection, path, `declares only the null type, which has no GraphQL projection`);\n\n\tif (type === undefined || type === \"object\") {\n\t\tconst named = enumType(projection, schema, preferred);\n\t\tif (named) return named;\n\t\tconst properties = Object.entries(schema.properties ?? {});\n\t\tif (properties.length === 0) {\n\t\t\t// A shape constrained to keys or values we cannot name is not \"anything\";\n\t\t\t// it is a map, and a map has no GraphQL projection.\n\t\t\tfor (const keyword of [\"patternProperties\", \"propertyNames\"] as const) {\n\t\t\t\tif (schema[keyword] !== undefined) unsupported(projection, path, `uses \"${keyword}\" with no declared properties, which has no GraphQL projection`);\n\t\t\t}\n\t\t\tif (schema.additionalProperties !== undefined && typeof schema.additionalProperties !== \"boolean\") {\n\t\t\t\tunsupported(projection, path, `constrains \"additionalProperties\" with no declared properties, which has no GraphQL projection`);\n\t\t\t}\n\t\t\t// Genuinely unconstrained: any JSON object is valid here.\n\t\t\treturn \"JSON\";\n\t\t}\n\t\tif (schema.patternProperties !== undefined) unsupported(projection, path, `uses \"patternProperties\" alongside \"properties\", which has no GraphQL projection`);\n\t\tconst name = reserve(projection, preferred);\n\t\tprojection.types.set(name, objectSdl(name, properties, schema, projection, path));\n\t\treturn name;\n\t}\n\n\tif (type === \"array\") {\n\t\tif (schema.prefixItems !== undefined) unsupported(projection, path, `uses \"prefixItems\", which has no GraphQL projection`);\n\t\tif (Array.isArray(schema.items)) unsupported(projection, path, `uses tuple \"items\", which has no GraphQL projection`);\n\t\t// A list whose element type is undeclared cannot be expressed as a GraphQL list.\n\t\tif (schema.items === undefined) unsupported(projection, path, `declares an array without \"items\", so its element type has no GraphQL projection`);\n\t\tconst item = schema.items;\n\t\tconst reference = project(item, `${preferred}Item`, projection, `${path}[]`);\n\t\treturn `[${reference}${admitsNull(item, projection) ? \"\" : \"!\"}]`;\n\t}\n\n\tconst named = enumType(projection, schema, preferred);\n\tif (named) return named;\n\tconst scalar = SCALARS[type];\n\tif (!scalar) unsupported(projection, path, `declares unsupported type \"${type}\"`);\n\treturn scalar;\n}\n\nfunction objectSdl(\n\tname: string,\n\tproperties: Array<[string, PortableJsonSchema]>,\n\tschema: PortableJsonSchema,\n\tprojection: Projection,\n\tpath: string,\n): string {\n\tconst required = new Set(schema.required ?? []);\n\tconst fieldNames = properties.map(([property]) => identifier(property));\n\tif (new Set(fieldNames).size !== fieldNames.length) {\n\t\tthrow new Error(`${projection.subject}${path} produces colliding GraphQL field names.`);\n\t}\n\tconst fields = properties.map(([property, child], index) => {\n\t\tconst reference = project(child, `${name}${pascal(property)}`, projection, `${path}.${property}`);\n\t\tconst nonNull = required.has(property) && !admitsNull(child, projection);\n\t\treturn ` ${fieldNames[index]}: ${reference}${nonNull ? \"!\" : \"\"}`;\n\t});\n\treturn `type ${name} {\\n${fields.join(\"\\n\")}\\n}`;\n}\n\nexport const graphqlGenerator: GeneratorTarget = {\n\tname: \"@fabricorg/gen-graphql\",\n\tversion: \"3.1.0\",\n\tgenerate(ir) {\n\t\treturn ir.modules.flatMap((module) => {\n\t\t\tconst namespaceType = pascal(module.namespace);\n\t\t\t// One registry per module: entity types, their nested types and every view\n\t\t\t// payload draw names from the same pool, so a collision is impossible rather\n\t\t\t// than merely unlikely.\n\t\t\tconst types = new Map<string, string>();\n\n\t\t\t// One projection per document, so a `$ref` in any property resolves against the\n\t\t\t// entity's own `$defs` rather than against that single property.\n\t\t\tconst projectionFor = (root: PortableJsonSchema, rootName: string, subject: string): Projection =>\n\t\t\t\t({ types, refs: new Map(), root, rootName, subject });\n\n\t\t\tfor (const objectType of module.objectTypes) {\n\t\t\t\tconst subject = `Module \"${module.namespace}\" object \"${objectType.type}\"`;\n\t\t\t\tconst schema = objectType.schema ?? {};\n\t\t\t\tconst required = new Set(schema.required ?? []);\n\t\t\t\tconst properties = Object.entries(schema.properties ?? {}).filter(([name]) => ![\"id\", \"tenantId\", \"spaceId\"].includes(name));\n\t\t\t\tconst fieldNames = properties.map(([name]) => identifier(name));\n\t\t\t\tif (new Set(fieldNames).size !== fieldNames.length) throw new Error(`Object \"${module.namespace}.${objectType.type}\" produces colliding GraphQL field names.`);\n\t\t\t\tconst entityName = `${namespaceType}${objectType.type}`;\n\t\t\t\tif (types.has(entityName)) throw new Error(`Module \"${module.namespace}\" produces two GraphQL types named \"${entityName}\".`);\n\t\t\t\ttypes.set(entityName, \"\");\n\t\t\t\tconst projection = projectionFor(schema, entityName, subject);\n\t\t\t\tfor (const keyword of [\"oneOf\", \"anyOf\", \"allOf\", \"not\", \"if\"] as const) {\n\t\t\t\t\tif (schema[keyword] !== undefined) unsupported(projection, \"\", `uses \"${keyword}\", which has no GraphQL projection`);\n\t\t\t\t}\n\t\t\t\tconst fields = properties.map(([name, child], index) => {\n\t\t\t\t\tconst reference = project(child, `${entityName}${pascal(name)}`, projection, `.${name}`);\n\t\t\t\t\tconst nonNull = required.has(name) && !admitsNull(child, projection);\n\t\t\t\t\treturn ` ${fieldNames[index]}: ${reference}${nonNull ? \"!\" : \"\"}`;\n\t\t\t\t});\n\t\t\t\ttypes.set(entityName, [`type ${entityName} @key(fields: \"id\") {`, \" id: ID!\", \" tenantId: ID!\", \" spaceId: ID!\", ...fields, \"}\"].join(\"\\n\"));\n\t\t\t}\n\n\t\t\tconst fieldName = (value: string): string => {\n\t\t\t\tconst name = pascal(value);\n\t\t\t\treturn `${name[0]?.toLowerCase() ?? \"\"}${name.slice(1)}`;\n\t\t\t};\n\n\t\t\tconst viewPayloads = module.views.map((view) => {\n\t\t\t\tconst rootName = `${pascal(view.name)}V${view.version.replace(/[^0-9A-Za-z]/g, \"_\")}`;\n\t\t\t\tconst projection = projectionFor(view.shape, rootName, `Module \"${module.namespace}\" view \"${view.name}@${view.version}\" shape`);\n\t\t\t\tconst reference = project(view.shape, rootName, projection, \"\");\n\t\t\t\treturn { field: fieldName(view.name), reference, nonNull: !admitsNull(view.shape, projection), parameterized: Boolean(view.parameterSchema) };\n\t\t\t});\n\n\t\t\tconst queryFields = viewPayloads.map((view) => ` ${view.field}${view.parameterized ? \"(parameters: JSON!)\" : \"\"}: ${view.reference}${view.nonNull ? \"!\" : \"\"}`);\n\t\t\tconst mutations = module.actions.map((action) => ` ${fieldName(action.actionId)}(parameters: JSON!): GovernedActionSubmission!`);\n\t\t\tconst operationNames = [...viewPayloads.map((view) => view.field), ...module.actions.map((action) => fieldName(action.actionId))];\n\t\t\tif (new Set(operationNames).size !== operationNames.length) throw new Error(`Module \"${module.namespace}\" produces colliding GraphQL operation names.`);\n\n\t\t\tconst content = [\n\t\t\t\t`# Generated by ${graphqlGenerator.name}@${graphqlGenerator.version}`,\n\t\t\t\t`# Manifest digest: ${ir.manifestDigest}`,\n\t\t\t\t'extend schema @link(url: \"https://specs.apollo.dev/federation/v2.7\", import: [\"@key\"])',\n\t\t\t\t\"scalar JSON\",\n\t\t\t\t\"type GovernedActionSubmission { actionInvocationId: ID!, status: String! }\",\n\t\t\t\t...[...types.values()].filter(Boolean),\n\t\t\t\t`type Query {\\n${queryFields.length ? queryFields.join(\"\\n\") : \" _fabric: Boolean!\"}\\n}`,\n\t\t\t\t`type Mutation {\\n${mutations.length ? mutations.join(\"\\n\") : \" _fabric: Boolean!\"}\\n}`,\n\t\t\t\t\"\",\n\t\t\t].join(\"\\n\\n\");\n\n\t\t\tconst actionIds = Object.fromEntries(module.actions.map((action) => [fieldName(action.actionId), action.actionId]));\n\t\t\tconst viewIds = Object.fromEntries(module.views.map((view) => [fieldName(view.name), { name: view.name, version: view.version }]));\n\n\t\t\tconst resolvers = [\n\t\t\t\t'import type { ProjectionHost, ProjectionQuery } from \"@fabricorg/projection-host\";',\n\t\t\t\t'import type { GovernedActionHost, SubmitActionInput, SubmitActionResult } from \"@fabricorg/platform-host\";',\n\t\t\t\t\"\",\n\t\t\t\t\"// Generated resolver seam. Authenticate first; derive actor and tenant server-side.\",\n\t\t\t\t`export const actionIds = ${JSON.stringify(actionIds, null, 2)} as const;`,\n\t\t\t\t`export const viewIds = ${JSON.stringify(viewIds, null, 2)} as const;`,\n\t\t\t\t\"\",\n\t\t\t\t'export async function resolveProjection(host: Pick<ProjectionHost, \"project\">, field: keyof typeof viewIds, context: Omit<ProjectionQuery, \"view\">): Promise<unknown> {',\n\t\t\t\t\" const result = await host.project({ ...context, view: viewIds[field] });\",\n\t\t\t\t\" return result.state;\",\n\t\t\t\t\"}\",\n\t\t\t\t'export type GovernedMutationContext = Omit<SubmitActionInput, \"actionId\" | \"parameters\">;',\n\t\t\t\t'export async function submitMutation(host: Pick<GovernedActionHost, \"submitAction\">, field: keyof typeof actionIds, parameters: Record<string, unknown>, context: GovernedMutationContext): Promise<SubmitActionResult> {',\n\t\t\t\t\" return await host.submitAction({ ...context, actionId: actionIds[field], parameters });\",\n\t\t\t\t\"}\",\n\t\t\t\t\"\",\n\t\t\t\t\"export interface ResolverWiring<TContext> {\",\n\t\t\t\t' projectionHost: Pick<ProjectionHost, \"project\">;',\n\t\t\t\t' actionHost: Pick<GovernedActionHost, \"submitAction\">;',\n\t\t\t\t\" /** Derive tenant, space and actor from the authenticated request. Never from client input. */\",\n\t\t\t\t' projectionContext: (context: TContext) => Omit<ProjectionQuery, \"view\"> | Promise<Omit<ProjectionQuery, \"view\">>;',\n\t\t\t\t\" mutationContext: (context: TContext) => GovernedMutationContext | Promise<GovernedMutationContext>;\",\n\t\t\t\t\"}\",\n\t\t\t\t\"\",\n\t\t\t\t\"/** Executable resolver map. Query fields read through ProjectionHost; Mutation fields submit through the governed Host. */\",\n\t\t\t\t\"export function createResolvers<TContext>(wiring: ResolverWiring<TContext>) {\",\n\t\t\t\t\" return {\",\n\t\t\t\t\" Query: {\",\n\t\t\t\t...viewPayloads.map((view) => view.parameterized\n\t\t\t\t\t? ` ${JSON.stringify(view.field)}: async (_parent: unknown, args: { parameters: unknown }, context: TContext) => resolveProjection(wiring.projectionHost, ${JSON.stringify(view.field)}, { ...await wiring.projectionContext(context), parameters: args.parameters }),`\n\t\t\t\t\t: ` ${JSON.stringify(view.field)}: async (_parent: unknown, _args: unknown, context: TContext) => resolveProjection(wiring.projectionHost, ${JSON.stringify(view.field)}, await wiring.projectionContext(context)),`,\n\t\t\t\t),\n\t\t\t\t\" },\",\n\t\t\t\t\" Mutation: {\",\n\t\t\t\t...Object.keys(actionIds).map((field) =>\n\t\t\t\t\t` ${JSON.stringify(field)}: async (_parent: unknown, args: { parameters: Record<string, unknown> }, context: TContext) => submitMutation(wiring.actionHost, ${JSON.stringify(field)}, args.parameters, await wiring.mutationContext(context)),`,\n\t\t\t\t),\n\t\t\t\t\" },\",\n\t\t\t\t\" };\",\n\t\t\t\t\"}\",\n\t\t\t\t\"\",\n\t\t\t].join(\"\\n\");\n\n\t\t\treturn [{ path: `${module.namespace}/schema.graphql`, content }, { path: `${module.namespace}/resolver-contract.ts`, content: resolvers }];\n\t\t});\n\t},\n};\n"],"mappings":"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","names":["named","module"]}
|
package/dist/index.js
CHANGED
|
@@ -129,7 +129,7 @@ ${fields.join("\n")}
|
|
|
129
129
|
}
|
|
130
130
|
var graphqlGenerator = {
|
|
131
131
|
name: "@fabricorg/gen-graphql",
|
|
132
|
-
version: "3.
|
|
132
|
+
version: "3.1.0",
|
|
133
133
|
generate(ir) {
|
|
134
134
|
return ir.modules.flatMap((module) => {
|
|
135
135
|
const namespaceType = pascal(module.namespace);
|
|
@@ -164,9 +164,9 @@ var graphqlGenerator = {
|
|
|
164
164
|
const rootName = `${pascal(view.name)}V${view.version.replace(/[^0-9A-Za-z]/g, "_")}`;
|
|
165
165
|
const projection = projectionFor(view.shape, rootName, `Module "${module.namespace}" view "${view.name}@${view.version}" shape`);
|
|
166
166
|
const reference = project(view.shape, rootName, projection, "");
|
|
167
|
-
return { field: fieldName(view.name), reference, nonNull: !admitsNull(view.shape, projection) };
|
|
167
|
+
return { field: fieldName(view.name), reference, nonNull: !admitsNull(view.shape, projection), parameterized: Boolean(view.parameterSchema) };
|
|
168
168
|
});
|
|
169
|
-
const queryFields = viewPayloads.map((view) => ` ${view.field}: ${view.reference}${view.nonNull ? "!" : ""}`);
|
|
169
|
+
const queryFields = viewPayloads.map((view) => ` ${view.field}${view.parameterized ? "(parameters: JSON!)" : ""}: ${view.reference}${view.nonNull ? "!" : ""}`);
|
|
170
170
|
const mutations = module.actions.map((action) => ` ${fieldName(action.actionId)}(parameters: JSON!): GovernedActionSubmission!`);
|
|
171
171
|
const operationNames = [...viewPayloads.map((view) => view.field), ...module.actions.map((action) => fieldName(action.actionId))];
|
|
172
172
|
if (new Set(operationNames).size !== operationNames.length) throw new Error(`Module "${module.namespace}" produces colliding GraphQL operation names.`);
|
|
@@ -216,8 +216,8 @@ ${mutations.length ? mutations.join("\n") : " _fabric: Boolean!"}
|
|
|
216
216
|
"export function createResolvers<TContext>(wiring: ResolverWiring<TContext>) {",
|
|
217
217
|
" return {",
|
|
218
218
|
" Query: {",
|
|
219
|
-
...
|
|
220
|
-
(field) => ` ${JSON.stringify(field)}: async (_parent: unknown, _args: unknown, context: TContext) => resolveProjection(wiring.projectionHost, ${JSON.stringify(field)}, await wiring.projectionContext(context)),`
|
|
219
|
+
...viewPayloads.map(
|
|
220
|
+
(view) => view.parameterized ? ` ${JSON.stringify(view.field)}: async (_parent: unknown, args: { parameters: unknown }, context: TContext) => resolveProjection(wiring.projectionHost, ${JSON.stringify(view.field)}, { ...await wiring.projectionContext(context), parameters: args.parameters }),` : ` ${JSON.stringify(view.field)}: async (_parent: unknown, _args: unknown, context: TContext) => resolveProjection(wiring.projectionHost, ${JSON.stringify(view.field)}, await wiring.projectionContext(context)),`
|
|
221
221
|
),
|
|
222
222
|
" },",
|
|
223
223
|
" Mutation: {",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"sourcesContent":["import type { GeneratorTarget } from \"@fabricorg/compiler\";\nimport type { PortableJsonSchema } from \"@fabricorg/platform\";\n\nconst pascal = (value: string): string =>\n\tvalue.split(/[-._/]/).filter(Boolean).map((part) => part[0]?.toUpperCase() + part.slice(1)).join(\"\");\n\nconst identifier = (value: string): string => {\n\tconst normalized = value.replace(/[^_0-9A-Za-z]/g, \"_\");\n\treturn /^[_A-Za-z]/.test(normalized) ? normalized : `field_${normalized}`;\n};\n\nconst SCALARS: Record<string, string> = { string: \"String\", integer: \"Int\", number: \"Float\", boolean: \"Boolean\" };\n\n/**\n * Named SDL blocks discovered while projecting one document, plus the `$defs`\n * names already claimed so a recursive `$ref` resolves to the type being built\n * rather than recursing forever.\n */\ninterface Projection {\n\t/** Insertion-ordered so emitted SDL is deterministic for a given manifest. Empty value means reserved-but-unfilled. */\n\ttypes: Map<string, string>;\n\trefs: Map<string, string>;\n\t/** The whole document, so a `$ref` in any property resolves against its `$defs`. */\n\troot: PortableJsonSchema;\n\trootName: string;\n\tsubject: string;\n}\n\nfunction unsupported(projection: Projection, path: string, reason: string): never {\n\tthrow new Error(`${projection.subject}${path} ${reason}. Give the view or object an explicit GraphQL-projectable shape.`);\n}\n\n/** Take a unique type name before projecting children, so a recursive `$ref` back to this type resolves to the same name. */\nfunction reserve(projection: Projection, preferred: string): string {\n\tlet name = preferred;\n\tfor (let suffix = 2; projection.types.has(name); suffix += 1) name = `${preferred}${suffix}`;\n\tprojection.types.set(name, \"\");\n\treturn name;\n}\n\n/** Resolve `#/$defs/<key>` only; any other pointer is not portable across generators. */\nfunction resolveRef(projection: Projection, ref: string, path: string): { schema: PortableJsonSchema; key: string } {\n\tconst match = /^#\\/\\$defs\\/([^/]+)$/.exec(ref);\n\tif (!match) unsupported(projection, path, `uses $ref \"${ref}\", which is not a local \"#/$defs/<name>\" pointer`);\n\tconst key = decodeURIComponent(match[1]!.replace(/~1/g, \"/\").replace(/~0/g, \"~\"));\n\tconst target = projection.root.$defs?.[key];\n\tif (!target) unsupported(projection, path, `references missing definition \"#/$defs/${key}\"`);\n\treturn { schema: target, key };\n}\n\n/** A shape that becomes a named GraphQL object type rather than a scalar, list or JSON. */\nfunction isObjectShape(schema: PortableJsonSchema): boolean {\n\treturn schema.$ref === undefined\n\t\t&& (schema.type === undefined || schema.type === \"object\")\n\t\t&& !Array.isArray(schema.enum)\n\t\t&& Object.keys(schema.properties ?? {}).length > 0;\n}\n\n/**\n * Whether a value may legitimately be null, following local refs. GraphQL\n * non-null is a promise to the client, so a required field whose definition\n * admits null must still be nullable.\n */\nfunction admitsNull(schema: PortableJsonSchema, projection: Projection, seen: Set<string> = new Set()): boolean {\n\tif (schema.$ref !== undefined) {\n\t\tconst match = /^#\\/\\$defs\\/([^/]+)$/.exec(schema.$ref);\n\t\tif (!match) return false;\n\t\tconst key = decodeURIComponent(match[1]!.replace(/~1/g, \"/\").replace(/~0/g, \"~\"));\n\t\tif (seen.has(key)) return false;\n\t\tseen.add(key);\n\t\tconst target = projection.root.$defs?.[key];\n\t\treturn target ? admitsNull(target, projection, seen) : false;\n\t}\n\tif (Array.isArray(schema.type)) return schema.type.includes(\"null\");\n\tif (schema.type === \"null\") return true;\n\treturn Array.isArray(schema.enum) ? schema.enum.includes(null) : false;\n}\n\nfunction enumType(projection: Projection, schema: PortableJsonSchema, preferred: string): string | undefined {\n\tconst values = schema.enum;\n\tif (!Array.isArray(values) || values.length === 0) return undefined;\n\tconst members = values.filter((value) => value !== null);\n\tif (members.length === 0) return undefined;\n\tif (!members.every((value) => typeof value === \"string\" && /^[_A-Za-z][_0-9A-Za-z]*$/.test(value))) return undefined;\n\tconst unique = [...new Set(members as string[])];\n\tconst name = reserve(projection, preferred);\n\tprojection.types.set(name, `enum ${name} {\\n${unique.map((member) => ` ${member}`).join(\"\\n\")}\\n}`);\n\treturn name;\n}\n\n/** Returns a GraphQL type reference without nullability; callers append `!`. */\nfunction project(schema: PortableJsonSchema, preferred: string, projection: Projection, path: string): string {\n\tfor (const keyword of [\"oneOf\", \"anyOf\", \"allOf\", \"not\", \"if\"] as const) {\n\t\tif (schema[keyword] !== undefined) unsupported(projection, path, `uses \"${keyword}\", which has no GraphQL projection`);\n\t}\n\n\tif (schema.$ref !== undefined) {\n\t\tconst { schema: target, key } = resolveRef(projection, schema.$ref, path);\n\t\tconst claimed = projection.refs.get(key);\n\t\tif (claimed) return claimed;\n\t\tconst preferredRefName = `${projection.rootName}${pascal(key)}`;\n\t\tif (isObjectShape(target)) {\n\t\t\t// Reserve before projecting the definition's own fields, so a definition that\n\t\t\t// refers back to itself resolves to this very name and nothing is ever unbound.\n\t\t\tconst name = reserve(projection, preferredRefName);\n\t\t\tprojection.refs.set(key, name);\n\t\t\tprojection.types.set(name, objectSdl(name, Object.entries(target.properties ?? {}), target, projection, `${path} -> $defs.${key}`));\n\t\t\treturn name;\n\t\t}\n\t\tconst projected = project(target, preferredRefName, projection, `${path} -> $defs.${key}`);\n\t\tprojection.refs.set(key, projected);\n\t\treturn projected;\n\t}\n\n\tconst declared = Array.isArray(schema.type) ? schema.type.filter((entry) => entry !== \"null\") : schema.type === undefined ? [] : [schema.type];\n\tif (Array.isArray(schema.type) && declared.length > 1) {\n\t\tunsupported(projection, path, `declares the union type [${schema.type.join(\", \")}], which has no GraphQL projection`);\n\t}\n\tif (Array.isArray(schema.type) && declared.length === 0) {\n\t\tunsupported(projection, path, `declares only the null type, which has no GraphQL projection`);\n\t}\n\tconst type = declared[0];\n\tif (type === \"null\") unsupported(projection, path, `declares only the null type, which has no GraphQL projection`);\n\n\tif (type === undefined || type === \"object\") {\n\t\tconst named = enumType(projection, schema, preferred);\n\t\tif (named) return named;\n\t\tconst properties = Object.entries(schema.properties ?? {});\n\t\tif (properties.length === 0) {\n\t\t\t// A shape constrained to keys or values we cannot name is not \"anything\";\n\t\t\t// it is a map, and a map has no GraphQL projection.\n\t\t\tfor (const keyword of [\"patternProperties\", \"propertyNames\"] as const) {\n\t\t\t\tif (schema[keyword] !== undefined) unsupported(projection, path, `uses \"${keyword}\" with no declared properties, which has no GraphQL projection`);\n\t\t\t}\n\t\t\tif (schema.additionalProperties !== undefined && typeof schema.additionalProperties !== \"boolean\") {\n\t\t\t\tunsupported(projection, path, `constrains \"additionalProperties\" with no declared properties, which has no GraphQL projection`);\n\t\t\t}\n\t\t\t// Genuinely unconstrained: any JSON object is valid here.\n\t\t\treturn \"JSON\";\n\t\t}\n\t\tif (schema.patternProperties !== undefined) unsupported(projection, path, `uses \"patternProperties\" alongside \"properties\", which has no GraphQL projection`);\n\t\tconst name = reserve(projection, preferred);\n\t\tprojection.types.set(name, objectSdl(name, properties, schema, projection, path));\n\t\treturn name;\n\t}\n\n\tif (type === \"array\") {\n\t\tif (schema.prefixItems !== undefined) unsupported(projection, path, `uses \"prefixItems\", which has no GraphQL projection`);\n\t\tif (Array.isArray(schema.items)) unsupported(projection, path, `uses tuple \"items\", which has no GraphQL projection`);\n\t\t// A list whose element type is undeclared cannot be expressed as a GraphQL list.\n\t\tif (schema.items === undefined) unsupported(projection, path, `declares an array without \"items\", so its element type has no GraphQL projection`);\n\t\tconst item = schema.items;\n\t\tconst reference = project(item, `${preferred}Item`, projection, `${path}[]`);\n\t\treturn `[${reference}${admitsNull(item, projection) ? \"\" : \"!\"}]`;\n\t}\n\n\tconst named = enumType(projection, schema, preferred);\n\tif (named) return named;\n\tconst scalar = SCALARS[type];\n\tif (!scalar) unsupported(projection, path, `declares unsupported type \"${type}\"`);\n\treturn scalar;\n}\n\nfunction objectSdl(\n\tname: string,\n\tproperties: Array<[string, PortableJsonSchema]>,\n\tschema: PortableJsonSchema,\n\tprojection: Projection,\n\tpath: string,\n): string {\n\tconst required = new Set(schema.required ?? []);\n\tconst fieldNames = properties.map(([property]) => identifier(property));\n\tif (new Set(fieldNames).size !== fieldNames.length) {\n\t\tthrow new Error(`${projection.subject}${path} produces colliding GraphQL field names.`);\n\t}\n\tconst fields = properties.map(([property, child], index) => {\n\t\tconst reference = project(child, `${name}${pascal(property)}`, projection, `${path}.${property}`);\n\t\tconst nonNull = required.has(property) && !admitsNull(child, projection);\n\t\treturn ` ${fieldNames[index]}: ${reference}${nonNull ? \"!\" : \"\"}`;\n\t});\n\treturn `type ${name} {\\n${fields.join(\"\\n\")}\\n}`;\n}\n\nexport const graphqlGenerator: GeneratorTarget = {\n\tname: \"@fabricorg/gen-graphql\",\n\tversion: \"3.0.0\",\n\tgenerate(ir) {\n\t\treturn ir.modules.flatMap((module) => {\n\t\t\tconst namespaceType = pascal(module.namespace);\n\t\t\t// One registry per module: entity types, their nested types and every view\n\t\t\t// payload draw names from the same pool, so a collision is impossible rather\n\t\t\t// than merely unlikely.\n\t\t\tconst types = new Map<string, string>();\n\n\t\t\t// One projection per document, so a `$ref` in any property resolves against the\n\t\t\t// entity's own `$defs` rather than against that single property.\n\t\t\tconst projectionFor = (root: PortableJsonSchema, rootName: string, subject: string): Projection =>\n\t\t\t\t({ types, refs: new Map(), root, rootName, subject });\n\n\t\t\tfor (const objectType of module.objectTypes) {\n\t\t\t\tconst subject = `Module \"${module.namespace}\" object \"${objectType.type}\"`;\n\t\t\t\tconst schema = objectType.schema ?? {};\n\t\t\t\tconst required = new Set(schema.required ?? []);\n\t\t\t\tconst properties = Object.entries(schema.properties ?? {}).filter(([name]) => ![\"id\", \"tenantId\", \"spaceId\"].includes(name));\n\t\t\t\tconst fieldNames = properties.map(([name]) => identifier(name));\n\t\t\t\tif (new Set(fieldNames).size !== fieldNames.length) throw new Error(`Object \"${module.namespace}.${objectType.type}\" produces colliding GraphQL field names.`);\n\t\t\t\tconst entityName = `${namespaceType}${objectType.type}`;\n\t\t\t\tif (types.has(entityName)) throw new Error(`Module \"${module.namespace}\" produces two GraphQL types named \"${entityName}\".`);\n\t\t\t\ttypes.set(entityName, \"\");\n\t\t\t\tconst projection = projectionFor(schema, entityName, subject);\n\t\t\t\tfor (const keyword of [\"oneOf\", \"anyOf\", \"allOf\", \"not\", \"if\"] as const) {\n\t\t\t\t\tif (schema[keyword] !== undefined) unsupported(projection, \"\", `uses \"${keyword}\", which has no GraphQL projection`);\n\t\t\t\t}\n\t\t\t\tconst fields = properties.map(([name, child], index) => {\n\t\t\t\t\tconst reference = project(child, `${entityName}${pascal(name)}`, projection, `.${name}`);\n\t\t\t\t\tconst nonNull = required.has(name) && !admitsNull(child, projection);\n\t\t\t\t\treturn ` ${fieldNames[index]}: ${reference}${nonNull ? \"!\" : \"\"}`;\n\t\t\t\t});\n\t\t\t\ttypes.set(entityName, [`type ${entityName} @key(fields: \"id\") {`, \" id: ID!\", \" tenantId: ID!\", \" spaceId: ID!\", ...fields, \"}\"].join(\"\\n\"));\n\t\t\t}\n\n\t\t\tconst fieldName = (value: string): string => {\n\t\t\t\tconst name = pascal(value);\n\t\t\t\treturn `${name[0]?.toLowerCase() ?? \"\"}${name.slice(1)}`;\n\t\t\t};\n\n\t\t\tconst viewPayloads = module.views.map((view) => {\n\t\t\t\tconst rootName = `${pascal(view.name)}V${view.version.replace(/[^0-9A-Za-z]/g, \"_\")}`;\n\t\t\t\tconst projection = projectionFor(view.shape, rootName, `Module \"${module.namespace}\" view \"${view.name}@${view.version}\" shape`);\n\t\t\t\tconst reference = project(view.shape, rootName, projection, \"\");\n\t\t\t\treturn { field: fieldName(view.name), reference, nonNull: !admitsNull(view.shape, projection) };\n\t\t\t});\n\n\t\t\tconst queryFields = viewPayloads.map((view) => ` ${view.field}: ${view.reference}${view.nonNull ? \"!\" : \"\"}`);\n\t\t\tconst mutations = module.actions.map((action) => ` ${fieldName(action.actionId)}(parameters: JSON!): GovernedActionSubmission!`);\n\t\t\tconst operationNames = [...viewPayloads.map((view) => view.field), ...module.actions.map((action) => fieldName(action.actionId))];\n\t\t\tif (new Set(operationNames).size !== operationNames.length) throw new Error(`Module \"${module.namespace}\" produces colliding GraphQL operation names.`);\n\n\t\t\tconst content = [\n\t\t\t\t`# Generated by ${graphqlGenerator.name}@${graphqlGenerator.version}`,\n\t\t\t\t`# Manifest digest: ${ir.manifestDigest}`,\n\t\t\t\t'extend schema @link(url: \"https://specs.apollo.dev/federation/v2.7\", import: [\"@key\"])',\n\t\t\t\t\"scalar JSON\",\n\t\t\t\t\"type GovernedActionSubmission { actionInvocationId: ID!, status: String! }\",\n\t\t\t\t...[...types.values()].filter(Boolean),\n\t\t\t\t`type Query {\\n${queryFields.length ? queryFields.join(\"\\n\") : \" _fabric: Boolean!\"}\\n}`,\n\t\t\t\t`type Mutation {\\n${mutations.length ? mutations.join(\"\\n\") : \" _fabric: Boolean!\"}\\n}`,\n\t\t\t\t\"\",\n\t\t\t].join(\"\\n\\n\");\n\n\t\t\tconst actionIds = Object.fromEntries(module.actions.map((action) => [fieldName(action.actionId), action.actionId]));\n\t\t\tconst viewIds = Object.fromEntries(module.views.map((view) => [fieldName(view.name), { name: view.name, version: view.version }]));\n\n\t\t\tconst resolvers = [\n\t\t\t\t'import type { ProjectionHost, ProjectionQuery } from \"@fabricorg/projection-host\";',\n\t\t\t\t'import type { GovernedActionHost, SubmitActionInput, SubmitActionResult } from \"@fabricorg/platform-host\";',\n\t\t\t\t\"\",\n\t\t\t\t\"// Generated resolver seam. Authenticate first; derive actor and tenant server-side.\",\n\t\t\t\t`export const actionIds = ${JSON.stringify(actionIds, null, 2)} as const;`,\n\t\t\t\t`export const viewIds = ${JSON.stringify(viewIds, null, 2)} as const;`,\n\t\t\t\t\"\",\n\t\t\t\t'export async function resolveProjection(host: Pick<ProjectionHost, \"project\">, field: keyof typeof viewIds, context: Omit<ProjectionQuery, \"view\">): Promise<unknown> {',\n\t\t\t\t\" const result = await host.project({ ...context, view: viewIds[field] });\",\n\t\t\t\t\" return result.state;\",\n\t\t\t\t\"}\",\n\t\t\t\t'export type GovernedMutationContext = Omit<SubmitActionInput, \"actionId\" | \"parameters\">;',\n\t\t\t\t'export async function submitMutation(host: Pick<GovernedActionHost, \"submitAction\">, field: keyof typeof actionIds, parameters: Record<string, unknown>, context: GovernedMutationContext): Promise<SubmitActionResult> {',\n\t\t\t\t\" return await host.submitAction({ ...context, actionId: actionIds[field], parameters });\",\n\t\t\t\t\"}\",\n\t\t\t\t\"\",\n\t\t\t\t\"export interface ResolverWiring<TContext> {\",\n\t\t\t\t' projectionHost: Pick<ProjectionHost, \"project\">;',\n\t\t\t\t' actionHost: Pick<GovernedActionHost, \"submitAction\">;',\n\t\t\t\t\" /** Derive tenant, space and actor from the authenticated request. Never from client input. */\",\n\t\t\t\t' projectionContext: (context: TContext) => Omit<ProjectionQuery, \"view\"> | Promise<Omit<ProjectionQuery, \"view\">>;',\n\t\t\t\t\" mutationContext: (context: TContext) => GovernedMutationContext | Promise<GovernedMutationContext>;\",\n\t\t\t\t\"}\",\n\t\t\t\t\"\",\n\t\t\t\t\"/** Executable resolver map. Query fields read through ProjectionHost; Mutation fields submit through the governed Host. */\",\n\t\t\t\t\"export function createResolvers<TContext>(wiring: ResolverWiring<TContext>) {\",\n\t\t\t\t\" return {\",\n\t\t\t\t\" Query: {\",\n\t\t\t\t...Object.keys(viewIds).map((field) =>\n\t\t\t\t\t` ${JSON.stringify(field)}: async (_parent: unknown, _args: unknown, context: TContext) => resolveProjection(wiring.projectionHost, ${JSON.stringify(field)}, await wiring.projectionContext(context)),`,\n\t\t\t\t),\n\t\t\t\t\" },\",\n\t\t\t\t\" Mutation: {\",\n\t\t\t\t...Object.keys(actionIds).map((field) =>\n\t\t\t\t\t` ${JSON.stringify(field)}: async (_parent: unknown, args: { parameters: Record<string, unknown> }, context: TContext) => submitMutation(wiring.actionHost, ${JSON.stringify(field)}, args.parameters, await wiring.mutationContext(context)),`,\n\t\t\t\t),\n\t\t\t\t\" },\",\n\t\t\t\t\" };\",\n\t\t\t\t\"}\",\n\t\t\t\t\"\",\n\t\t\t].join(\"\\n\");\n\n\t\t\treturn [{ path: `${module.namespace}/schema.graphql`, content }, { path: `${module.namespace}/resolver-contract.ts`, content: resolvers }];\n\t\t});\n\t},\n};\n"],"mappings":"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","names":["named"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"sourcesContent":["import type { GeneratorTarget } from \"@fabricorg/compiler\";\nimport type { PortableJsonSchema } from \"@fabricorg/platform\";\n\nconst pascal = (value: string): string =>\n\tvalue.split(/[-._/]/).filter(Boolean).map((part) => part[0]?.toUpperCase() + part.slice(1)).join(\"\");\n\nconst identifier = (value: string): string => {\n\tconst normalized = value.replace(/[^_0-9A-Za-z]/g, \"_\");\n\treturn /^[_A-Za-z]/.test(normalized) ? normalized : `field_${normalized}`;\n};\n\nconst SCALARS: Record<string, string> = { string: \"String\", integer: \"Int\", number: \"Float\", boolean: \"Boolean\" };\n\n/**\n * Named SDL blocks discovered while projecting one document, plus the `$defs`\n * names already claimed so a recursive `$ref` resolves to the type being built\n * rather than recursing forever.\n */\ninterface Projection {\n\t/** Insertion-ordered so emitted SDL is deterministic for a given manifest. Empty value means reserved-but-unfilled. */\n\ttypes: Map<string, string>;\n\trefs: Map<string, string>;\n\t/** The whole document, so a `$ref` in any property resolves against its `$defs`. */\n\troot: PortableJsonSchema;\n\trootName: string;\n\tsubject: string;\n}\n\nfunction unsupported(projection: Projection, path: string, reason: string): never {\n\tthrow new Error(`${projection.subject}${path} ${reason}. Give the view or object an explicit GraphQL-projectable shape.`);\n}\n\n/** Take a unique type name before projecting children, so a recursive `$ref` back to this type resolves to the same name. */\nfunction reserve(projection: Projection, preferred: string): string {\n\tlet name = preferred;\n\tfor (let suffix = 2; projection.types.has(name); suffix += 1) name = `${preferred}${suffix}`;\n\tprojection.types.set(name, \"\");\n\treturn name;\n}\n\n/** Resolve `#/$defs/<key>` only; any other pointer is not portable across generators. */\nfunction resolveRef(projection: Projection, ref: string, path: string): { schema: PortableJsonSchema; key: string } {\n\tconst match = /^#\\/\\$defs\\/([^/]+)$/.exec(ref);\n\tif (!match) unsupported(projection, path, `uses $ref \"${ref}\", which is not a local \"#/$defs/<name>\" pointer`);\n\tconst key = decodeURIComponent(match[1]!.replace(/~1/g, \"/\").replace(/~0/g, \"~\"));\n\tconst target = projection.root.$defs?.[key];\n\tif (!target) unsupported(projection, path, `references missing definition \"#/$defs/${key}\"`);\n\treturn { schema: target, key };\n}\n\n/** A shape that becomes a named GraphQL object type rather than a scalar, list or JSON. */\nfunction isObjectShape(schema: PortableJsonSchema): boolean {\n\treturn schema.$ref === undefined\n\t\t&& (schema.type === undefined || schema.type === \"object\")\n\t\t&& !Array.isArray(schema.enum)\n\t\t&& Object.keys(schema.properties ?? {}).length > 0;\n}\n\n/**\n * Whether a value may legitimately be null, following local refs. GraphQL\n * non-null is a promise to the client, so a required field whose definition\n * admits null must still be nullable.\n */\nfunction admitsNull(schema: PortableJsonSchema, projection: Projection, seen: Set<string> = new Set()): boolean {\n\tif (schema.$ref !== undefined) {\n\t\tconst match = /^#\\/\\$defs\\/([^/]+)$/.exec(schema.$ref);\n\t\tif (!match) return false;\n\t\tconst key = decodeURIComponent(match[1]!.replace(/~1/g, \"/\").replace(/~0/g, \"~\"));\n\t\tif (seen.has(key)) return false;\n\t\tseen.add(key);\n\t\tconst target = projection.root.$defs?.[key];\n\t\treturn target ? admitsNull(target, projection, seen) : false;\n\t}\n\tif (Array.isArray(schema.type)) return schema.type.includes(\"null\");\n\tif (schema.type === \"null\") return true;\n\treturn Array.isArray(schema.enum) ? schema.enum.includes(null) : false;\n}\n\nfunction enumType(projection: Projection, schema: PortableJsonSchema, preferred: string): string | undefined {\n\tconst values = schema.enum;\n\tif (!Array.isArray(values) || values.length === 0) return undefined;\n\tconst members = values.filter((value) => value !== null);\n\tif (members.length === 0) return undefined;\n\tif (!members.every((value) => typeof value === \"string\" && /^[_A-Za-z][_0-9A-Za-z]*$/.test(value))) return undefined;\n\tconst unique = [...new Set(members as string[])];\n\tconst name = reserve(projection, preferred);\n\tprojection.types.set(name, `enum ${name} {\\n${unique.map((member) => ` ${member}`).join(\"\\n\")}\\n}`);\n\treturn name;\n}\n\n/** Returns a GraphQL type reference without nullability; callers append `!`. */\nfunction project(schema: PortableJsonSchema, preferred: string, projection: Projection, path: string): string {\n\tfor (const keyword of [\"oneOf\", \"anyOf\", \"allOf\", \"not\", \"if\"] as const) {\n\t\tif (schema[keyword] !== undefined) unsupported(projection, path, `uses \"${keyword}\", which has no GraphQL projection`);\n\t}\n\n\tif (schema.$ref !== undefined) {\n\t\tconst { schema: target, key } = resolveRef(projection, schema.$ref, path);\n\t\tconst claimed = projection.refs.get(key);\n\t\tif (claimed) return claimed;\n\t\tconst preferredRefName = `${projection.rootName}${pascal(key)}`;\n\t\tif (isObjectShape(target)) {\n\t\t\t// Reserve before projecting the definition's own fields, so a definition that\n\t\t\t// refers back to itself resolves to this very name and nothing is ever unbound.\n\t\t\tconst name = reserve(projection, preferredRefName);\n\t\t\tprojection.refs.set(key, name);\n\t\t\tprojection.types.set(name, objectSdl(name, Object.entries(target.properties ?? {}), target, projection, `${path} -> $defs.${key}`));\n\t\t\treturn name;\n\t\t}\n\t\tconst projected = project(target, preferredRefName, projection, `${path} -> $defs.${key}`);\n\t\tprojection.refs.set(key, projected);\n\t\treturn projected;\n\t}\n\n\tconst declared = Array.isArray(schema.type) ? schema.type.filter((entry) => entry !== \"null\") : schema.type === undefined ? [] : [schema.type];\n\tif (Array.isArray(schema.type) && declared.length > 1) {\n\t\tunsupported(projection, path, `declares the union type [${schema.type.join(\", \")}], which has no GraphQL projection`);\n\t}\n\tif (Array.isArray(schema.type) && declared.length === 0) {\n\t\tunsupported(projection, path, `declares only the null type, which has no GraphQL projection`);\n\t}\n\tconst type = declared[0];\n\tif (type === \"null\") unsupported(projection, path, `declares only the null type, which has no GraphQL projection`);\n\n\tif (type === undefined || type === \"object\") {\n\t\tconst named = enumType(projection, schema, preferred);\n\t\tif (named) return named;\n\t\tconst properties = Object.entries(schema.properties ?? {});\n\t\tif (properties.length === 0) {\n\t\t\t// A shape constrained to keys or values we cannot name is not \"anything\";\n\t\t\t// it is a map, and a map has no GraphQL projection.\n\t\t\tfor (const keyword of [\"patternProperties\", \"propertyNames\"] as const) {\n\t\t\t\tif (schema[keyword] !== undefined) unsupported(projection, path, `uses \"${keyword}\" with no declared properties, which has no GraphQL projection`);\n\t\t\t}\n\t\t\tif (schema.additionalProperties !== undefined && typeof schema.additionalProperties !== \"boolean\") {\n\t\t\t\tunsupported(projection, path, `constrains \"additionalProperties\" with no declared properties, which has no GraphQL projection`);\n\t\t\t}\n\t\t\t// Genuinely unconstrained: any JSON object is valid here.\n\t\t\treturn \"JSON\";\n\t\t}\n\t\tif (schema.patternProperties !== undefined) unsupported(projection, path, `uses \"patternProperties\" alongside \"properties\", which has no GraphQL projection`);\n\t\tconst name = reserve(projection, preferred);\n\t\tprojection.types.set(name, objectSdl(name, properties, schema, projection, path));\n\t\treturn name;\n\t}\n\n\tif (type === \"array\") {\n\t\tif (schema.prefixItems !== undefined) unsupported(projection, path, `uses \"prefixItems\", which has no GraphQL projection`);\n\t\tif (Array.isArray(schema.items)) unsupported(projection, path, `uses tuple \"items\", which has no GraphQL projection`);\n\t\t// A list whose element type is undeclared cannot be expressed as a GraphQL list.\n\t\tif (schema.items === undefined) unsupported(projection, path, `declares an array without \"items\", so its element type has no GraphQL projection`);\n\t\tconst item = schema.items;\n\t\tconst reference = project(item, `${preferred}Item`, projection, `${path}[]`);\n\t\treturn `[${reference}${admitsNull(item, projection) ? \"\" : \"!\"}]`;\n\t}\n\n\tconst named = enumType(projection, schema, preferred);\n\tif (named) return named;\n\tconst scalar = SCALARS[type];\n\tif (!scalar) unsupported(projection, path, `declares unsupported type \"${type}\"`);\n\treturn scalar;\n}\n\nfunction objectSdl(\n\tname: string,\n\tproperties: Array<[string, PortableJsonSchema]>,\n\tschema: PortableJsonSchema,\n\tprojection: Projection,\n\tpath: string,\n): string {\n\tconst required = new Set(schema.required ?? []);\n\tconst fieldNames = properties.map(([property]) => identifier(property));\n\tif (new Set(fieldNames).size !== fieldNames.length) {\n\t\tthrow new Error(`${projection.subject}${path} produces colliding GraphQL field names.`);\n\t}\n\tconst fields = properties.map(([property, child], index) => {\n\t\tconst reference = project(child, `${name}${pascal(property)}`, projection, `${path}.${property}`);\n\t\tconst nonNull = required.has(property) && !admitsNull(child, projection);\n\t\treturn ` ${fieldNames[index]}: ${reference}${nonNull ? \"!\" : \"\"}`;\n\t});\n\treturn `type ${name} {\\n${fields.join(\"\\n\")}\\n}`;\n}\n\nexport const graphqlGenerator: GeneratorTarget = {\n\tname: \"@fabricorg/gen-graphql\",\n\tversion: \"3.1.0\",\n\tgenerate(ir) {\n\t\treturn ir.modules.flatMap((module) => {\n\t\t\tconst namespaceType = pascal(module.namespace);\n\t\t\t// One registry per module: entity types, their nested types and every view\n\t\t\t// payload draw names from the same pool, so a collision is impossible rather\n\t\t\t// than merely unlikely.\n\t\t\tconst types = new Map<string, string>();\n\n\t\t\t// One projection per document, so a `$ref` in any property resolves against the\n\t\t\t// entity's own `$defs` rather than against that single property.\n\t\t\tconst projectionFor = (root: PortableJsonSchema, rootName: string, subject: string): Projection =>\n\t\t\t\t({ types, refs: new Map(), root, rootName, subject });\n\n\t\t\tfor (const objectType of module.objectTypes) {\n\t\t\t\tconst subject = `Module \"${module.namespace}\" object \"${objectType.type}\"`;\n\t\t\t\tconst schema = objectType.schema ?? {};\n\t\t\t\tconst required = new Set(schema.required ?? []);\n\t\t\t\tconst properties = Object.entries(schema.properties ?? {}).filter(([name]) => ![\"id\", \"tenantId\", \"spaceId\"].includes(name));\n\t\t\t\tconst fieldNames = properties.map(([name]) => identifier(name));\n\t\t\t\tif (new Set(fieldNames).size !== fieldNames.length) throw new Error(`Object \"${module.namespace}.${objectType.type}\" produces colliding GraphQL field names.`);\n\t\t\t\tconst entityName = `${namespaceType}${objectType.type}`;\n\t\t\t\tif (types.has(entityName)) throw new Error(`Module \"${module.namespace}\" produces two GraphQL types named \"${entityName}\".`);\n\t\t\t\ttypes.set(entityName, \"\");\n\t\t\t\tconst projection = projectionFor(schema, entityName, subject);\n\t\t\t\tfor (const keyword of [\"oneOf\", \"anyOf\", \"allOf\", \"not\", \"if\"] as const) {\n\t\t\t\t\tif (schema[keyword] !== undefined) unsupported(projection, \"\", `uses \"${keyword}\", which has no GraphQL projection`);\n\t\t\t\t}\n\t\t\t\tconst fields = properties.map(([name, child], index) => {\n\t\t\t\t\tconst reference = project(child, `${entityName}${pascal(name)}`, projection, `.${name}`);\n\t\t\t\t\tconst nonNull = required.has(name) && !admitsNull(child, projection);\n\t\t\t\t\treturn ` ${fieldNames[index]}: ${reference}${nonNull ? \"!\" : \"\"}`;\n\t\t\t\t});\n\t\t\t\ttypes.set(entityName, [`type ${entityName} @key(fields: \"id\") {`, \" id: ID!\", \" tenantId: ID!\", \" spaceId: ID!\", ...fields, \"}\"].join(\"\\n\"));\n\t\t\t}\n\n\t\t\tconst fieldName = (value: string): string => {\n\t\t\t\tconst name = pascal(value);\n\t\t\t\treturn `${name[0]?.toLowerCase() ?? \"\"}${name.slice(1)}`;\n\t\t\t};\n\n\t\t\tconst viewPayloads = module.views.map((view) => {\n\t\t\t\tconst rootName = `${pascal(view.name)}V${view.version.replace(/[^0-9A-Za-z]/g, \"_\")}`;\n\t\t\t\tconst projection = projectionFor(view.shape, rootName, `Module \"${module.namespace}\" view \"${view.name}@${view.version}\" shape`);\n\t\t\t\tconst reference = project(view.shape, rootName, projection, \"\");\n\t\t\t\treturn { field: fieldName(view.name), reference, nonNull: !admitsNull(view.shape, projection), parameterized: Boolean(view.parameterSchema) };\n\t\t\t});\n\n\t\t\tconst queryFields = viewPayloads.map((view) => ` ${view.field}${view.parameterized ? \"(parameters: JSON!)\" : \"\"}: ${view.reference}${view.nonNull ? \"!\" : \"\"}`);\n\t\t\tconst mutations = module.actions.map((action) => ` ${fieldName(action.actionId)}(parameters: JSON!): GovernedActionSubmission!`);\n\t\t\tconst operationNames = [...viewPayloads.map((view) => view.field), ...module.actions.map((action) => fieldName(action.actionId))];\n\t\t\tif (new Set(operationNames).size !== operationNames.length) throw new Error(`Module \"${module.namespace}\" produces colliding GraphQL operation names.`);\n\n\t\t\tconst content = [\n\t\t\t\t`# Generated by ${graphqlGenerator.name}@${graphqlGenerator.version}`,\n\t\t\t\t`# Manifest digest: ${ir.manifestDigest}`,\n\t\t\t\t'extend schema @link(url: \"https://specs.apollo.dev/federation/v2.7\", import: [\"@key\"])',\n\t\t\t\t\"scalar JSON\",\n\t\t\t\t\"type GovernedActionSubmission { actionInvocationId: ID!, status: String! }\",\n\t\t\t\t...[...types.values()].filter(Boolean),\n\t\t\t\t`type Query {\\n${queryFields.length ? queryFields.join(\"\\n\") : \" _fabric: Boolean!\"}\\n}`,\n\t\t\t\t`type Mutation {\\n${mutations.length ? mutations.join(\"\\n\") : \" _fabric: Boolean!\"}\\n}`,\n\t\t\t\t\"\",\n\t\t\t].join(\"\\n\\n\");\n\n\t\t\tconst actionIds = Object.fromEntries(module.actions.map((action) => [fieldName(action.actionId), action.actionId]));\n\t\t\tconst viewIds = Object.fromEntries(module.views.map((view) => [fieldName(view.name), { name: view.name, version: view.version }]));\n\n\t\t\tconst resolvers = [\n\t\t\t\t'import type { ProjectionHost, ProjectionQuery } from \"@fabricorg/projection-host\";',\n\t\t\t\t'import type { GovernedActionHost, SubmitActionInput, SubmitActionResult } from \"@fabricorg/platform-host\";',\n\t\t\t\t\"\",\n\t\t\t\t\"// Generated resolver seam. Authenticate first; derive actor and tenant server-side.\",\n\t\t\t\t`export const actionIds = ${JSON.stringify(actionIds, null, 2)} as const;`,\n\t\t\t\t`export const viewIds = ${JSON.stringify(viewIds, null, 2)} as const;`,\n\t\t\t\t\"\",\n\t\t\t\t'export async function resolveProjection(host: Pick<ProjectionHost, \"project\">, field: keyof typeof viewIds, context: Omit<ProjectionQuery, \"view\">): Promise<unknown> {',\n\t\t\t\t\" const result = await host.project({ ...context, view: viewIds[field] });\",\n\t\t\t\t\" return result.state;\",\n\t\t\t\t\"}\",\n\t\t\t\t'export type GovernedMutationContext = Omit<SubmitActionInput, \"actionId\" | \"parameters\">;',\n\t\t\t\t'export async function submitMutation(host: Pick<GovernedActionHost, \"submitAction\">, field: keyof typeof actionIds, parameters: Record<string, unknown>, context: GovernedMutationContext): Promise<SubmitActionResult> {',\n\t\t\t\t\" return await host.submitAction({ ...context, actionId: actionIds[field], parameters });\",\n\t\t\t\t\"}\",\n\t\t\t\t\"\",\n\t\t\t\t\"export interface ResolverWiring<TContext> {\",\n\t\t\t\t' projectionHost: Pick<ProjectionHost, \"project\">;',\n\t\t\t\t' actionHost: Pick<GovernedActionHost, \"submitAction\">;',\n\t\t\t\t\" /** Derive tenant, space and actor from the authenticated request. Never from client input. */\",\n\t\t\t\t' projectionContext: (context: TContext) => Omit<ProjectionQuery, \"view\"> | Promise<Omit<ProjectionQuery, \"view\">>;',\n\t\t\t\t\" mutationContext: (context: TContext) => GovernedMutationContext | Promise<GovernedMutationContext>;\",\n\t\t\t\t\"}\",\n\t\t\t\t\"\",\n\t\t\t\t\"/** Executable resolver map. Query fields read through ProjectionHost; Mutation fields submit through the governed Host. */\",\n\t\t\t\t\"export function createResolvers<TContext>(wiring: ResolverWiring<TContext>) {\",\n\t\t\t\t\" return {\",\n\t\t\t\t\" Query: {\",\n\t\t\t\t...viewPayloads.map((view) => view.parameterized\n\t\t\t\t\t? ` ${JSON.stringify(view.field)}: async (_parent: unknown, args: { parameters: unknown }, context: TContext) => resolveProjection(wiring.projectionHost, ${JSON.stringify(view.field)}, { ...await wiring.projectionContext(context), parameters: args.parameters }),`\n\t\t\t\t\t: ` ${JSON.stringify(view.field)}: async (_parent: unknown, _args: unknown, context: TContext) => resolveProjection(wiring.projectionHost, ${JSON.stringify(view.field)}, await wiring.projectionContext(context)),`,\n\t\t\t\t),\n\t\t\t\t\" },\",\n\t\t\t\t\" Mutation: {\",\n\t\t\t\t...Object.keys(actionIds).map((field) =>\n\t\t\t\t\t` ${JSON.stringify(field)}: async (_parent: unknown, args: { parameters: Record<string, unknown> }, context: TContext) => submitMutation(wiring.actionHost, ${JSON.stringify(field)}, args.parameters, await wiring.mutationContext(context)),`,\n\t\t\t\t),\n\t\t\t\t\" },\",\n\t\t\t\t\" };\",\n\t\t\t\t\"}\",\n\t\t\t\t\"\",\n\t\t\t].join(\"\\n\");\n\n\t\t\treturn [{ path: `${module.namespace}/schema.graphql`, content }, { path: `${module.namespace}/resolver-contract.ts`, content: resolvers }];\n\t\t});\n\t},\n};\n"],"mappings":"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","names":["named"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fabricorg/gen-graphql",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Federation-ready GraphQL contract generator for Fabric compiler IR.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -25,20 +25,20 @@
|
|
|
25
25
|
"CHANGELOG.md"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@fabricorg/compiler": "^2.
|
|
28
|
+
"@fabricorg/compiler": "^2.2.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"@fabricorg/platform": "^
|
|
32
|
-
"@fabricorg/platform
|
|
33
|
-
"@fabricorg/projection-host": "^1.
|
|
31
|
+
"@fabricorg/platform-host": "^5.0.0 || ^6.0.0",
|
|
32
|
+
"@fabricorg/platform": "^1.2.0",
|
|
33
|
+
"@fabricorg/projection-host": "^1.1.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^22.10.0",
|
|
37
37
|
"tsup": "^8.5.0",
|
|
38
38
|
"typescript": "^5.7.3",
|
|
39
39
|
"vitest": "^4.1.5",
|
|
40
|
-
"@fabricorg/platform
|
|
41
|
-
"@fabricorg/platform": "^
|
|
40
|
+
"@fabricorg/platform": "^1.2.0",
|
|
41
|
+
"@fabricorg/platform-host": "^6.0.0"
|
|
42
42
|
},
|
|
43
43
|
"engines": {
|
|
44
44
|
"node": ">=20"
|