instant-cli 1.0.40-branch-python-sdk-v1.26482536960.1 → 1.0.40-branch-python-sdk-v1.26483086955.1

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.
@@ -1,4 +1,4 @@
1
1
 
2
- > instant-cli@1.0.40-branch-python-sdk-v1.26482536960.1 build /home/runner/work/instant/instant/client/packages/cli
2
+ > instant-cli@1.0.40-branch-python-sdk-v1.26483086955.1 build /home/runner/work/instant/instant/client/packages/cli
3
3
  > rm -rf dist; tsc -p tsconfig.build.json
4
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"genpy.d.ts","sourceRoot":"","sources":["../../src/commands/genpy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;;;;;;AAE9B,qBAAa,eAAgB,SAAQ,oBAInC;CAAG;AAML,eAAO,MAAM,YAAY,GAAI,YAAY;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,+HAgDxD,CAAC;AAIL,KAAK,UAAU,GAAG;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACpC,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CACxC,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAC7D,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,CAAC;IAC5D,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,CAAC;CAC7D,CAAC;AAmCF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAoJ9D;AA8FD,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA0GzD"}
1
+ {"version":3,"file":"genpy.d.ts","sourceRoot":"","sources":["../../src/commands/genpy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;;;;;;AAE9B,qBAAa,eAAgB,SAAQ,oBAInC;CAAG;AAML,eAAO,MAAM,YAAY,GAAI,YAAY;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,+HAwDxD,CAAC;AAIL,KAAK,UAAU,GAAG;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACpC,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CACxC,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAC7D,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,CAAC;IAC5D,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,CAAC;CAC7D,CAAC;AAmCF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAuJ9D;AAoGD,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA6GzD"}
@@ -32,14 +32,22 @@ export const genpyCommand = ({ outDir }) => Effect.gen(function* () {
32
32
  // Default: write alongside the schema file. `--out-dir` overrides for
33
33
  // monorepos where Python lives elsewhere, or for our own sandbox where
34
34
  // the schema is shared with the JS CLI tests.
35
- const targetDir = outDir ? path.resolve(outDir) : path.dirname(localSchemaFile.path);
36
- yield* fs.makeDirectory(targetDir, { recursive: true }).pipe(Effect.mapError((e) => GenpyWriteError.make({ message: `Failed to create ${targetDir}: ${e}` })));
35
+ const targetDir = outDir
36
+ ? path.resolve(outDir)
37
+ : path.dirname(localSchemaFile.path);
38
+ yield* fs.makeDirectory(targetDir, { recursive: true }).pipe(Effect.mapError((e) => GenpyWriteError.make({
39
+ message: `Failed to create ${targetDir}: ${e}`,
40
+ })));
37
41
  const pyPath = path.join(targetDir, 'instant_types.py');
38
42
  const pyiPath = path.join(targetDir, 'instant_types.pyi');
39
43
  const pyContent = buildEntityModelsPy(localSchemaFile.schema);
40
44
  const pyiContent = buildTxStubPyi(localSchemaFile.schema);
41
- yield* fs.writeFileString(pyPath, pyContent).pipe(Effect.mapError((e) => GenpyWriteError.make({ message: `Failed to write ${pyPath}: ${e}` })));
42
- yield* fs.writeFileString(pyiPath, pyiContent).pipe(Effect.mapError((e) => GenpyWriteError.make({ message: `Failed to write ${pyiPath}: ${e}` })));
45
+ yield* fs
46
+ .writeFileString(pyPath, pyContent)
47
+ .pipe(Effect.mapError((e) => GenpyWriteError.make({ message: `Failed to write ${pyPath}: ${e}` })));
48
+ yield* fs
49
+ .writeFileString(pyiPath, pyiContent)
50
+ .pipe(Effect.mapError((e) => GenpyWriteError.make({ message: `Failed to write ${pyiPath}: ${e}` })));
43
51
  yield* Effect.log(`✅ Wrote ${pyPath} and ${pyiPath}`);
44
52
  });
45
53
  function className(entName) {
@@ -143,7 +151,8 @@ export function buildEntityModelsPy(schema) {
143
151
  if (usesDatetime)
144
152
  stdlibImports.push('from datetime import datetime');
145
153
  stdlibImports.push(`from typing import ${typingImports.join(', ')}`);
146
- const importBlock = stdlibImports.join('\n') + '\n\n' +
154
+ const importBlock = stdlibImports.join('\n') +
155
+ '\n\n' +
147
156
  'from pydantic import BaseModel, ConfigDict';
148
157
  // Add record-model rebuilds so forward-string annotations to entity
149
158
  // types resolve under `from __future__ import annotations`.
@@ -249,7 +258,11 @@ function buildWebhookSection(schema, entityNames) {
249
258
  }
250
259
  const rootUnionTerms = entityNames.map((n) => `${className(n)}Record`);
251
260
  const rootUnion = `WebhookRecord = ${rootUnionTerms.join(' | ')}`;
252
- const handlerDictLines = ['WebhookHandlers = TypedDict(', ' "WebhookHandlers",', ' {'];
261
+ const handlerDictLines = [
262
+ 'WebhookHandlers = TypedDict(',
263
+ ' "WebhookHandlers",',
264
+ ' {',
265
+ ];
253
266
  for (const entName of entityNames) {
254
267
  handlerDictLines.push(` ${JSON.stringify(entName)}: _${className(entName)}Handlers,`);
255
268
  }
@@ -353,7 +366,8 @@ export function buildTxStubPyi(schema) {
353
366
  if (usesDatetime)
354
367
  stdlibImports.unshift('from datetime import datetime');
355
368
  return [
356
- PY_HEADER + '"""Tx builder typing stub. Applied via `Instant(schema=...)`."""',
369
+ PY_HEADER +
370
+ '"""Tx builder typing stub. Applied via `Instant(schema=...)`."""',
357
371
  '',
358
372
  'from __future__ import annotations',
359
373
  '',
@@ -1 +1 @@
1
- {"version":3,"file":"genpy.js","sourceRoot":"","sources":["../../src/commands/genpy.ts"],"names":[],"mappings":"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","sourcesContent":["import { FileSystem, Path } from '@effect/platform';\nimport chalk from 'chalk';\nimport { Effect, Schema } from 'effect';\nimport { readLocalSchemaFile } from '../old.js';\nimport {\n ReadSchemaFileError,\n SchemaValidationError,\n} from '../lib/pushSchema.ts';\n\nexport class GenpyWriteError extends Schema.TaggedError<GenpyWriteError>(\n 'GenpyWriteError',\n)('GenpyWriteError', {\n message: Schema.String,\n}) {}\n\nconst PY_HEADER = `# AUTOGENERATED by \\`instant-cli genpy\\`. DO NOT EDIT THIS FILE BY HAND.\n# Re-run \\`npx instant-cli genpy\\` after schema changes.\n`;\n\nexport const genpyCommand = ({ outDir }: { outDir?: string }) =>\n Effect.gen(function* () {\n const localSchemaFile = yield* Effect.tryPromise({\n try: readLocalSchemaFile,\n catch: (e) =>\n e instanceof Error\n ? ReadSchemaFileError.make({ message: e.message })\n : ReadSchemaFileError.make({ message: String(e) }),\n });\n if (!localSchemaFile || !localSchemaFile.schema) {\n return yield* ReadSchemaFileError.make({\n message: `We couldn't find your ${chalk.yellow('`instant.schema.ts`')} file. Make sure it's in the project root or under \\`src/\\`. (Hint: set INSTANT_SCHEMA_FILE_PATH to override.)`,\n });\n }\n if (localSchemaFile.schema.constructor?.name !== 'InstantSchemaDef') {\n return yield* SchemaValidationError.make({\n message: `We couldn't find your schema export.\\nIn your ${chalk.yellow('`instant.schema.ts`')} file, make sure you ${chalk.green('`export default schema`')}`,\n });\n }\n\n const path = yield* Path.Path;\n const fs = yield* FileSystem.FileSystem;\n // Default: write alongside the schema file. `--out-dir` overrides for\n // monorepos where Python lives elsewhere, or for our own sandbox where\n // the schema is shared with the JS CLI tests.\n const targetDir = outDir ? path.resolve(outDir) : path.dirname(localSchemaFile.path);\n yield* fs.makeDirectory(targetDir, { recursive: true }).pipe(\n Effect.mapError((e) =>\n GenpyWriteError.make({ message: `Failed to create ${targetDir}: ${e}` }),\n ),\n );\n const pyPath = path.join(targetDir, 'instant_types.py');\n const pyiPath = path.join(targetDir, 'instant_types.pyi');\n\n const pyContent = buildEntityModelsPy(localSchemaFile.schema);\n const pyiContent = buildTxStubPyi(localSchemaFile.schema);\n yield* fs.writeFileString(pyPath, pyContent).pipe(\n Effect.mapError((e) =>\n GenpyWriteError.make({ message: `Failed to write ${pyPath}: ${e}` }),\n ),\n );\n yield* fs.writeFileString(pyiPath, pyiContent).pipe(\n Effect.mapError((e) =>\n GenpyWriteError.make({ message: `Failed to write ${pyiPath}: ${e}` }),\n ),\n );\n\n yield* Effect.log(`✅ Wrote ${pyPath} and ${pyiPath}`);\n });\n\n// ---------- entity model codegen ----------\n\ntype SchemaLike = {\n entities: Record<string, EntityDefLike>;\n links: Record<string, LinkDefLike>;\n};\n\ntype EntityDefLike = {\n attrs: Record<string, DataAttrDefLike>;\n};\n\ntype DataAttrDefLike = {\n valueType: 'string' | 'number' | 'boolean' | 'date' | 'json';\n required: boolean;\n};\n\ntype LinkDefLike = {\n forward: { on: string; label: string; has: 'one' | 'many' };\n reverse: { on: string; label: string; has: 'one' | 'many' };\n};\n\ntype Field = { name: string; type: string; hasDefault: boolean };\n\nfunction className(entName: string): string {\n // Strip a leading `$` (system entities like `$users`, `$files`), then\n // PascalCase across word separators (`-`, `_`, whitespace) so non-identifier\n // characters in entity names don't produce invalid Python class names.\n const stripped = entName.startsWith('$') ? entName.slice(1) : entName;\n return stripped\n .split(/[-_\\s]+/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n\nfunction mapValueType(vt: DataAttrDefLike['valueType']): string {\n switch (vt) {\n case 'string':\n return 'str';\n case 'number':\n return 'float';\n case 'boolean':\n return 'bool';\n case 'date':\n return 'datetime';\n case 'json':\n return 'Any';\n default:\n // Defensive: if a new valueType ever lands in the schema without a\n // genpy update, fall back to Any so generated code stays valid Python.\n return 'Any';\n }\n}\n\nexport function buildEntityModelsPy(schema: SchemaLike): string {\n const entityNames = Object.keys(schema.entities).sort();\n const fieldsByEntity: Record<string, Field[]> = {};\n const linkFieldsByEntity: Record<string, Field[]> = {};\n let usesDatetime = false;\n\n for (const entName of entityNames) {\n fieldsByEntity[entName] = [{ name: 'id', type: 'str', hasDefault: false }];\n linkFieldsByEntity[entName] = [];\n for (const [attrName, attrDef] of Object.entries(\n schema.entities[entName].attrs,\n )) {\n const baseType = mapValueType(attrDef.valueType);\n if (baseType === 'datetime') usesDatetime = true;\n const type = attrDef.required ? baseType : `${baseType} | None`;\n fieldsByEntity[entName].push({\n name: attrName,\n type,\n hasDefault: !attrDef.required,\n });\n }\n }\n\n for (const link of Object.values(schema.links)) {\n const fwd = link.forward;\n const rev = link.reverse;\n if (linkFieldsByEntity[fwd.on]) {\n linkFieldsByEntity[fwd.on].push({\n name: fwd.label,\n type:\n fwd.has === 'one'\n ? `${className(rev.on)} | None`\n : `list[${className(rev.on)}] | None`,\n hasDefault: true,\n });\n }\n if (linkFieldsByEntity[rev.on]) {\n linkFieldsByEntity[rev.on].push({\n name: rev.label,\n type:\n rev.has === 'one'\n ? `${className(fwd.on)} | None`\n : `list[${className(fwd.on)}] | None`,\n hasDefault: true,\n });\n }\n }\n\n // Sort link fields alphabetically for stable output across schema rewrites.\n for (const entName of entityNames) {\n linkFieldsByEntity[entName].sort((a, b) => a.name.localeCompare(b.name));\n }\n\n const classBlocks = entityNames.map((entName) => {\n const lines = [\n `class ${className(entName)}(BaseModel):`,\n ` model_config = ConfigDict(extra=\"ignore\")`,\n ];\n for (const f of [\n ...fieldsByEntity[entName],\n ...linkFieldsByEntity[entName],\n ]) {\n const decl = f.hasDefault\n ? ` ${f.name}: ${f.type} = None`\n : ` ${f.name}: ${f.type}`;\n lines.push(decl);\n }\n return lines.join('\\n');\n });\n\n const rebuilds = entityNames.map(\n (entName) => `${className(entName)}.model_rebuild()`,\n );\n\n // Webhook record / handler types live in the same .py so users get one\n // import point (`from instant_types import ...`) for both query results\n // and webhook handler type-checking.\n const webhookSection = buildWebhookSection(schema, entityNames);\n\n const typingImports = ['Any', 'Callable', 'Literal', 'TypedDict'];\n\n const stdlibImports: string[] = [];\n if (usesDatetime) stdlibImports.push('from datetime import datetime');\n stdlibImports.push(`from typing import ${typingImports.join(', ')}`);\n const importBlock =\n stdlibImports.join('\\n') + '\\n\\n' +\n 'from pydantic import BaseModel, ConfigDict';\n\n // Add record-model rebuilds so forward-string annotations to entity\n // types resolve under `from __future__ import annotations`.\n const recordRebuilds: string[] = [];\n for (const entName of entityNames) {\n const cls = className(entName);\n for (const action of ['Create', 'Update', 'Delete']) {\n recordRebuilds.push(`${cls}${action}Record.model_rebuild()`);\n }\n }\n\n // Registry consumed by `Instant(schema=schema)`.\n const entityMapLines = [' \"entities\": {'];\n for (const entName of entityNames) {\n entityMapLines.push(` ${JSON.stringify(entName)}: ${className(entName)},`);\n }\n entityMapLines.push(' },');\n const recordMapLines = [' \"records\": {'];\n for (const entName of entityNames) {\n const cls = className(entName);\n for (const action of ['create', 'update', 'delete']) {\n const capAction = action.charAt(0).toUpperCase() + action.slice(1);\n recordMapLines.push(\n ` (${JSON.stringify(entName)}, ${JSON.stringify(action)}): ${cls}${capAction}Record,`,\n );\n }\n }\n recordMapLines.push(' },');\n const schemaLiteral = [\n 'schema = {',\n ...entityMapLines,\n ...recordMapLines,\n '}',\n ].join('\\n');\n\n return [\n PY_HEADER + '\"\"\"Generated Pydantic models for Instant schema.\"\"\"',\n '',\n 'from __future__ import annotations',\n '',\n importBlock,\n '',\n '',\n classBlocks.join('\\n\\n\\n'),\n '',\n '',\n '# Resolve forward references introduced by `from __future__ import annotations`.',\n rebuilds.join('\\n'),\n '',\n '',\n webhookSection,\n '',\n '',\n '# Rebuild webhook records so `before` / `after` annotations resolve to entity classes.',\n recordRebuilds.join('\\n'),\n '',\n '',\n '# Registry consumed by `Instant(schema=schema)` for query-result + webhook validation.',\n schemaLiteral,\n '',\n ].join('\\n');\n}\n\n// ---------- webhook record / handler codegen ----------\n\nfunction buildWebhookSection(\n schema: SchemaLike,\n entityNames: string[],\n): string {\n // Schemas with zero entities would produce `WebhookRecord = ` (no RHS).\n if (entityNames.length === 0) return '';\n\n const recordClasses: string[] = [];\n const namespaceUnions: string[] = [];\n const namespaceHandlerDicts: string[] = [];\n\n // `before`/`after` shape varies by action.\n const RECORD_VARIANTS = [\n { action: 'create', before: 'None = None', afterTpl: (c: string) => c },\n { action: 'update', before: 'CLS', afterTpl: (c: string) => c },\n { action: 'delete', before: 'CLS', afterTpl: () => 'None = None' },\n ] as const;\n\n for (const entName of entityNames) {\n const cls = className(entName);\n for (const { action, before, afterTpl } of RECORD_VARIANTS) {\n const cap = action.charAt(0).toUpperCase() + action.slice(1);\n recordClasses.push(\n [\n `class ${cls}${cap}Record(BaseModel):`,\n ` model_config = ConfigDict(extra=\"ignore\")`,\n ` namespace: Literal[${JSON.stringify(entName)}] = ${JSON.stringify(entName)}`,\n ` id: str`,\n ` action: Literal[${JSON.stringify(action)}] = ${JSON.stringify(action)}`,\n ` before: ${before === 'CLS' ? cls : before}`,\n ` after: ${afterTpl(cls)}`,\n ` idempotencyKey: str`,\n ].join('\\n'),\n );\n }\n\n namespaceUnions.push(\n `${cls}Record = ${cls}CreateRecord | ${cls}UpdateRecord | ${cls}DeleteRecord`,\n );\n\n // Per-namespace handler TypedDict. Functional syntax so the `$default`\n // key is expressible.\n namespaceHandlerDicts.push(\n [\n `_${cls}Handlers = TypedDict(`,\n ` \"_${cls}Handlers\",`,\n ' {',\n ` \"create\": Callable[[${cls}CreateRecord], Any],`,\n ` \"update\": Callable[[${cls}UpdateRecord], Any],`,\n ` \"delete\": Callable[[${cls}DeleteRecord], Any],`,\n ` \"$default\": Callable[[${cls}Record], Any],`,\n ' },',\n ' total=False,',\n ')',\n ].join('\\n'),\n );\n }\n\n const rootUnionTerms = entityNames.map((n) => `${className(n)}Record`);\n const rootUnion = `WebhookRecord = ${rootUnionTerms.join(' | ')}`;\n\n const handlerDictLines = ['WebhookHandlers = TypedDict(', ' \"WebhookHandlers\",', ' {'];\n for (const entName of entityNames) {\n handlerDictLines.push(` ${JSON.stringify(entName)}: _${className(entName)}Handlers,`);\n }\n handlerDictLines.push(` \"$default\": Callable[[WebhookRecord], Any],`);\n handlerDictLines.push(' },', ' total=False,', ')');\n\n return [\n '# ---------- webhook record models ----------',\n '',\n recordClasses.join('\\n\\n\\n'),\n '',\n '',\n '# ---------- webhook handler types ----------',\n '',\n namespaceUnions.join('\\n'),\n '',\n rootUnion,\n '',\n '',\n namespaceHandlerDicts.join('\\n\\n\\n'),\n '',\n '',\n handlerDictLines.join('\\n'),\n ].join('\\n');\n}\n\n// ---------- tx builder .pyi stub ----------\n\nexport function buildTxStubPyi(schema: SchemaLike): string {\n const entityNames = Object.keys(schema.entities).sort();\n let usesDatetime = false;\n\n // Per-entity link fields (label + arg type for link/unlink TypedDict).\n const linkFieldsByEntity: Record<string, { label: string; type: string }[]> =\n {};\n for (const entName of entityNames) {\n linkFieldsByEntity[entName] = [];\n }\n for (const link of Object.values(schema.links)) {\n const fwdArgType = link.forward.has === 'one' ? 'str' : 'str | list[str]';\n const revArgType = link.reverse.has === 'one' ? 'str' : 'str | list[str]';\n if (linkFieldsByEntity[link.forward.on]) {\n linkFieldsByEntity[link.forward.on].push({\n label: link.forward.label,\n type: fwdArgType,\n });\n }\n if (linkFieldsByEntity[link.reverse.on]) {\n linkFieldsByEntity[link.reverse.on].push({\n label: link.reverse.label,\n type: revArgType,\n });\n }\n }\n for (const entName of entityNames) {\n linkFieldsByEntity[entName].sort((a, b) => a.label.localeCompare(b.label));\n }\n\n const perEntityBlocks: string[] = [];\n for (const entName of entityNames) {\n const cls = className(entName);\n\n const argsLines = [`class ${cls}Args(TypedDict, total=False):`];\n for (const [attrName, attrDef] of Object.entries(\n schema.entities[entName].attrs,\n )) {\n const t = mapValueType(attrDef.valueType);\n if (t === 'datetime') usesDatetime = true;\n argsLines.push(` ${attrName}: ${t}`);\n }\n if (argsLines.length === 1) argsLines.push(' pass');\n perEntityBlocks.push(argsLines.join('\\n'));\n\n const linkLines = [`class ${cls}Links(TypedDict, total=False):`];\n for (const link of linkFieldsByEntity[entName]) {\n linkLines.push(` ${link.label}: ${link.type}`);\n }\n if (linkLines.length === 1) linkLines.push(' pass');\n perEntityBlocks.push(linkLines.join('\\n'));\n\n perEntityBlocks.push(\n [\n `class _${cls}Chunk:`,\n ` def update(self, args: ${cls}Args) -> _${cls}Chunk: ...`,\n ` def create(self, args: ${cls}Args) -> _${cls}Chunk: ...`,\n ` def link(self, args: ${cls}Links) -> _${cls}Chunk: ...`,\n ` def unlink(self, args: ${cls}Links) -> _${cls}Chunk: ...`,\n ` def delete(self) -> _${cls}Chunk: ...`,\n ` def merge(self, args: ${cls}Args) -> _${cls}Chunk: ...`,\n ].join('\\n'),\n );\n }\n\n const builderBlock = [\n 'class _NamespaceBuilder(Generic[ChunkT]):',\n ' def __getitem__(self, eid: str) -> ChunkT: ...',\n ' def lookup(self, attr: str, value: Any) -> ChunkT: ...',\n ].join('\\n');\n\n // `$`-prefixed entities can't be reached via attribute syntax, so omit\n // them from `_TxBuilder` attrs. Subscript form (`db.tx[\"$users\"]`) still works.\n const identifierEntities = entityNames.filter((n) => !n.startsWith('$'));\n const txLines = ['class _TxBuilder:'];\n if (identifierEntities.length === 0) {\n txLines.push(' pass');\n } else {\n for (const entName of identifierEntities) {\n txLines.push(` ${entName}: _NamespaceBuilder[_${className(entName)}Chunk]`);\n }\n }\n\n const stdlibImports = ['from typing import Any, Generic, TypedDict, TypeVar'];\n if (usesDatetime) stdlibImports.unshift('from datetime import datetime');\n\n return [\n PY_HEADER + '\"\"\"Tx builder typing stub. Applied via `Instant(schema=...)`.\"\"\"',\n '',\n 'from __future__ import annotations',\n '',\n stdlibImports.join('\\n'),\n '',\n '',\n 'ChunkT = TypeVar(\"ChunkT\")',\n '',\n '',\n perEntityBlocks.join('\\n\\n\\n'),\n '',\n '',\n builderBlock,\n '',\n '',\n txLines.join('\\n'),\n '',\n ].join('\\n');\n}\n"]}
1
+ {"version":3,"file":"genpy.js","sourceRoot":"","sources":["../../src/commands/genpy.ts"],"names":[],"mappings":"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","sourcesContent":["import { FileSystem, Path } from '@effect/platform';\nimport chalk from 'chalk';\nimport { Effect, Schema } from 'effect';\nimport { readLocalSchemaFile } from '../old.js';\nimport {\n ReadSchemaFileError,\n SchemaValidationError,\n} from '../lib/pushSchema.ts';\n\nexport class GenpyWriteError extends Schema.TaggedError<GenpyWriteError>(\n 'GenpyWriteError',\n)('GenpyWriteError', {\n message: Schema.String,\n}) {}\n\nconst PY_HEADER = `# AUTOGENERATED by \\`instant-cli genpy\\`. DO NOT EDIT THIS FILE BY HAND.\n# Re-run \\`npx instant-cli genpy\\` after schema changes.\n`;\n\nexport const genpyCommand = ({ outDir }: { outDir?: string }) =>\n Effect.gen(function* () {\n const localSchemaFile = yield* Effect.tryPromise({\n try: readLocalSchemaFile,\n catch: (e) =>\n e instanceof Error\n ? ReadSchemaFileError.make({ message: e.message })\n : ReadSchemaFileError.make({ message: String(e) }),\n });\n if (!localSchemaFile || !localSchemaFile.schema) {\n return yield* ReadSchemaFileError.make({\n message: `We couldn't find your ${chalk.yellow('`instant.schema.ts`')} file. Make sure it's in the project root or under \\`src/\\`. (Hint: set INSTANT_SCHEMA_FILE_PATH to override.)`,\n });\n }\n if (localSchemaFile.schema.constructor?.name !== 'InstantSchemaDef') {\n return yield* SchemaValidationError.make({\n message: `We couldn't find your schema export.\\nIn your ${chalk.yellow('`instant.schema.ts`')} file, make sure you ${chalk.green('`export default schema`')}`,\n });\n }\n\n const path = yield* Path.Path;\n const fs = yield* FileSystem.FileSystem;\n // Default: write alongside the schema file. `--out-dir` overrides for\n // monorepos where Python lives elsewhere, or for our own sandbox where\n // the schema is shared with the JS CLI tests.\n const targetDir = outDir\n ? path.resolve(outDir)\n : path.dirname(localSchemaFile.path);\n yield* fs.makeDirectory(targetDir, { recursive: true }).pipe(\n Effect.mapError((e) =>\n GenpyWriteError.make({\n message: `Failed to create ${targetDir}: ${e}`,\n }),\n ),\n );\n const pyPath = path.join(targetDir, 'instant_types.py');\n const pyiPath = path.join(targetDir, 'instant_types.pyi');\n\n const pyContent = buildEntityModelsPy(localSchemaFile.schema);\n const pyiContent = buildTxStubPyi(localSchemaFile.schema);\n yield* fs\n .writeFileString(pyPath, pyContent)\n .pipe(\n Effect.mapError((e) =>\n GenpyWriteError.make({ message: `Failed to write ${pyPath}: ${e}` }),\n ),\n );\n yield* fs\n .writeFileString(pyiPath, pyiContent)\n .pipe(\n Effect.mapError((e) =>\n GenpyWriteError.make({ message: `Failed to write ${pyiPath}: ${e}` }),\n ),\n );\n\n yield* Effect.log(`✅ Wrote ${pyPath} and ${pyiPath}`);\n });\n\n// ---------- entity model codegen ----------\n\ntype SchemaLike = {\n entities: Record<string, EntityDefLike>;\n links: Record<string, LinkDefLike>;\n};\n\ntype EntityDefLike = {\n attrs: Record<string, DataAttrDefLike>;\n};\n\ntype DataAttrDefLike = {\n valueType: 'string' | 'number' | 'boolean' | 'date' | 'json';\n required: boolean;\n};\n\ntype LinkDefLike = {\n forward: { on: string; label: string; has: 'one' | 'many' };\n reverse: { on: string; label: string; has: 'one' | 'many' };\n};\n\ntype Field = { name: string; type: string; hasDefault: boolean };\n\nfunction className(entName: string): string {\n // Strip a leading `$` (system entities like `$users`, `$files`), then\n // PascalCase across word separators (`-`, `_`, whitespace) so non-identifier\n // characters in entity names don't produce invalid Python class names.\n const stripped = entName.startsWith('$') ? entName.slice(1) : entName;\n return stripped\n .split(/[-_\\s]+/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n\nfunction mapValueType(vt: DataAttrDefLike['valueType']): string {\n switch (vt) {\n case 'string':\n return 'str';\n case 'number':\n return 'float';\n case 'boolean':\n return 'bool';\n case 'date':\n return 'datetime';\n case 'json':\n return 'Any';\n default:\n // Defensive: if a new valueType ever lands in the schema without a\n // genpy update, fall back to Any so generated code stays valid Python.\n return 'Any';\n }\n}\n\nexport function buildEntityModelsPy(schema: SchemaLike): string {\n const entityNames = Object.keys(schema.entities).sort();\n const fieldsByEntity: Record<string, Field[]> = {};\n const linkFieldsByEntity: Record<string, Field[]> = {};\n let usesDatetime = false;\n\n for (const entName of entityNames) {\n fieldsByEntity[entName] = [{ name: 'id', type: 'str', hasDefault: false }];\n linkFieldsByEntity[entName] = [];\n for (const [attrName, attrDef] of Object.entries(\n schema.entities[entName].attrs,\n )) {\n const baseType = mapValueType(attrDef.valueType);\n if (baseType === 'datetime') usesDatetime = true;\n const type = attrDef.required ? baseType : `${baseType} | None`;\n fieldsByEntity[entName].push({\n name: attrName,\n type,\n hasDefault: !attrDef.required,\n });\n }\n }\n\n for (const link of Object.values(schema.links)) {\n const fwd = link.forward;\n const rev = link.reverse;\n if (linkFieldsByEntity[fwd.on]) {\n linkFieldsByEntity[fwd.on].push({\n name: fwd.label,\n type:\n fwd.has === 'one'\n ? `${className(rev.on)} | None`\n : `list[${className(rev.on)}] | None`,\n hasDefault: true,\n });\n }\n if (linkFieldsByEntity[rev.on]) {\n linkFieldsByEntity[rev.on].push({\n name: rev.label,\n type:\n rev.has === 'one'\n ? `${className(fwd.on)} | None`\n : `list[${className(fwd.on)}] | None`,\n hasDefault: true,\n });\n }\n }\n\n // Sort link fields alphabetically for stable output across schema rewrites.\n for (const entName of entityNames) {\n linkFieldsByEntity[entName].sort((a, b) => a.name.localeCompare(b.name));\n }\n\n const classBlocks = entityNames.map((entName) => {\n const lines = [\n `class ${className(entName)}(BaseModel):`,\n ` model_config = ConfigDict(extra=\"ignore\")`,\n ];\n for (const f of [\n ...fieldsByEntity[entName],\n ...linkFieldsByEntity[entName],\n ]) {\n const decl = f.hasDefault\n ? ` ${f.name}: ${f.type} = None`\n : ` ${f.name}: ${f.type}`;\n lines.push(decl);\n }\n return lines.join('\\n');\n });\n\n const rebuilds = entityNames.map(\n (entName) => `${className(entName)}.model_rebuild()`,\n );\n\n // Webhook record / handler types live in the same .py so users get one\n // import point (`from instant_types import ...`) for both query results\n // and webhook handler type-checking.\n const webhookSection = buildWebhookSection(schema, entityNames);\n\n const typingImports = ['Any', 'Callable', 'Literal', 'TypedDict'];\n\n const stdlibImports: string[] = [];\n if (usesDatetime) stdlibImports.push('from datetime import datetime');\n stdlibImports.push(`from typing import ${typingImports.join(', ')}`);\n const importBlock =\n stdlibImports.join('\\n') +\n '\\n\\n' +\n 'from pydantic import BaseModel, ConfigDict';\n\n // Add record-model rebuilds so forward-string annotations to entity\n // types resolve under `from __future__ import annotations`.\n const recordRebuilds: string[] = [];\n for (const entName of entityNames) {\n const cls = className(entName);\n for (const action of ['Create', 'Update', 'Delete']) {\n recordRebuilds.push(`${cls}${action}Record.model_rebuild()`);\n }\n }\n\n // Registry consumed by `Instant(schema=schema)`.\n const entityMapLines = [' \"entities\": {'];\n for (const entName of entityNames) {\n entityMapLines.push(\n ` ${JSON.stringify(entName)}: ${className(entName)},`,\n );\n }\n entityMapLines.push(' },');\n const recordMapLines = [' \"records\": {'];\n for (const entName of entityNames) {\n const cls = className(entName);\n for (const action of ['create', 'update', 'delete']) {\n const capAction = action.charAt(0).toUpperCase() + action.slice(1);\n recordMapLines.push(\n ` (${JSON.stringify(entName)}, ${JSON.stringify(action)}): ${cls}${capAction}Record,`,\n );\n }\n }\n recordMapLines.push(' },');\n const schemaLiteral = [\n 'schema = {',\n ...entityMapLines,\n ...recordMapLines,\n '}',\n ].join('\\n');\n\n return [\n PY_HEADER + '\"\"\"Generated Pydantic models for Instant schema.\"\"\"',\n '',\n 'from __future__ import annotations',\n '',\n importBlock,\n '',\n '',\n classBlocks.join('\\n\\n\\n'),\n '',\n '',\n '# Resolve forward references introduced by `from __future__ import annotations`.',\n rebuilds.join('\\n'),\n '',\n '',\n webhookSection,\n '',\n '',\n '# Rebuild webhook records so `before` / `after` annotations resolve to entity classes.',\n recordRebuilds.join('\\n'),\n '',\n '',\n '# Registry consumed by `Instant(schema=schema)` for query-result + webhook validation.',\n schemaLiteral,\n '',\n ].join('\\n');\n}\n\n// ---------- webhook record / handler codegen ----------\n\nfunction buildWebhookSection(\n schema: SchemaLike,\n entityNames: string[],\n): string {\n // Schemas with zero entities would produce `WebhookRecord = ` (no RHS).\n if (entityNames.length === 0) return '';\n\n const recordClasses: string[] = [];\n const namespaceUnions: string[] = [];\n const namespaceHandlerDicts: string[] = [];\n\n // `before`/`after` shape varies by action.\n const RECORD_VARIANTS = [\n { action: 'create', before: 'None = None', afterTpl: (c: string) => c },\n { action: 'update', before: 'CLS', afterTpl: (c: string) => c },\n { action: 'delete', before: 'CLS', afterTpl: () => 'None = None' },\n ] as const;\n\n for (const entName of entityNames) {\n const cls = className(entName);\n for (const { action, before, afterTpl } of RECORD_VARIANTS) {\n const cap = action.charAt(0).toUpperCase() + action.slice(1);\n recordClasses.push(\n [\n `class ${cls}${cap}Record(BaseModel):`,\n ` model_config = ConfigDict(extra=\"ignore\")`,\n ` namespace: Literal[${JSON.stringify(entName)}] = ${JSON.stringify(entName)}`,\n ` id: str`,\n ` action: Literal[${JSON.stringify(action)}] = ${JSON.stringify(action)}`,\n ` before: ${before === 'CLS' ? cls : before}`,\n ` after: ${afterTpl(cls)}`,\n ` idempotencyKey: str`,\n ].join('\\n'),\n );\n }\n\n namespaceUnions.push(\n `${cls}Record = ${cls}CreateRecord | ${cls}UpdateRecord | ${cls}DeleteRecord`,\n );\n\n // Per-namespace handler TypedDict. Functional syntax so the `$default`\n // key is expressible.\n namespaceHandlerDicts.push(\n [\n `_${cls}Handlers = TypedDict(`,\n ` \"_${cls}Handlers\",`,\n ' {',\n ` \"create\": Callable[[${cls}CreateRecord], Any],`,\n ` \"update\": Callable[[${cls}UpdateRecord], Any],`,\n ` \"delete\": Callable[[${cls}DeleteRecord], Any],`,\n ` \"$default\": Callable[[${cls}Record], Any],`,\n ' },',\n ' total=False,',\n ')',\n ].join('\\n'),\n );\n }\n\n const rootUnionTerms = entityNames.map((n) => `${className(n)}Record`);\n const rootUnion = `WebhookRecord = ${rootUnionTerms.join(' | ')}`;\n\n const handlerDictLines = [\n 'WebhookHandlers = TypedDict(',\n ' \"WebhookHandlers\",',\n ' {',\n ];\n for (const entName of entityNames) {\n handlerDictLines.push(\n ` ${JSON.stringify(entName)}: _${className(entName)}Handlers,`,\n );\n }\n handlerDictLines.push(` \"$default\": Callable[[WebhookRecord], Any],`);\n handlerDictLines.push(' },', ' total=False,', ')');\n\n return [\n '# ---------- webhook record models ----------',\n '',\n recordClasses.join('\\n\\n\\n'),\n '',\n '',\n '# ---------- webhook handler types ----------',\n '',\n namespaceUnions.join('\\n'),\n '',\n rootUnion,\n '',\n '',\n namespaceHandlerDicts.join('\\n\\n\\n'),\n '',\n '',\n handlerDictLines.join('\\n'),\n ].join('\\n');\n}\n\n// ---------- tx builder .pyi stub ----------\n\nexport function buildTxStubPyi(schema: SchemaLike): string {\n const entityNames = Object.keys(schema.entities).sort();\n let usesDatetime = false;\n\n // Per-entity link fields (label + arg type for link/unlink TypedDict).\n const linkFieldsByEntity: Record<string, { label: string; type: string }[]> =\n {};\n for (const entName of entityNames) {\n linkFieldsByEntity[entName] = [];\n }\n for (const link of Object.values(schema.links)) {\n const fwdArgType = link.forward.has === 'one' ? 'str' : 'str | list[str]';\n const revArgType = link.reverse.has === 'one' ? 'str' : 'str | list[str]';\n if (linkFieldsByEntity[link.forward.on]) {\n linkFieldsByEntity[link.forward.on].push({\n label: link.forward.label,\n type: fwdArgType,\n });\n }\n if (linkFieldsByEntity[link.reverse.on]) {\n linkFieldsByEntity[link.reverse.on].push({\n label: link.reverse.label,\n type: revArgType,\n });\n }\n }\n for (const entName of entityNames) {\n linkFieldsByEntity[entName].sort((a, b) => a.label.localeCompare(b.label));\n }\n\n const perEntityBlocks: string[] = [];\n for (const entName of entityNames) {\n const cls = className(entName);\n\n const argsLines = [`class ${cls}Args(TypedDict, total=False):`];\n for (const [attrName, attrDef] of Object.entries(\n schema.entities[entName].attrs,\n )) {\n const t = mapValueType(attrDef.valueType);\n if (t === 'datetime') usesDatetime = true;\n argsLines.push(` ${attrName}: ${t}`);\n }\n if (argsLines.length === 1) argsLines.push(' pass');\n perEntityBlocks.push(argsLines.join('\\n'));\n\n const linkLines = [`class ${cls}Links(TypedDict, total=False):`];\n for (const link of linkFieldsByEntity[entName]) {\n linkLines.push(` ${link.label}: ${link.type}`);\n }\n if (linkLines.length === 1) linkLines.push(' pass');\n perEntityBlocks.push(linkLines.join('\\n'));\n\n perEntityBlocks.push(\n [\n `class _${cls}Chunk:`,\n ` def update(self, args: ${cls}Args) -> _${cls}Chunk: ...`,\n ` def create(self, args: ${cls}Args) -> _${cls}Chunk: ...`,\n ` def link(self, args: ${cls}Links) -> _${cls}Chunk: ...`,\n ` def unlink(self, args: ${cls}Links) -> _${cls}Chunk: ...`,\n ` def delete(self) -> _${cls}Chunk: ...`,\n ` def merge(self, args: ${cls}Args) -> _${cls}Chunk: ...`,\n ].join('\\n'),\n );\n }\n\n const builderBlock = [\n 'class _NamespaceBuilder(Generic[ChunkT]):',\n ' def __getitem__(self, eid: str) -> ChunkT: ...',\n ' def lookup(self, attr: str, value: Any) -> ChunkT: ...',\n ].join('\\n');\n\n // `$`-prefixed entities can't be reached via attribute syntax, so omit\n // them from `_TxBuilder` attrs. Subscript form (`db.tx[\"$users\"]`) still works.\n const identifierEntities = entityNames.filter((n) => !n.startsWith('$'));\n const txLines = ['class _TxBuilder:'];\n if (identifierEntities.length === 0) {\n txLines.push(' pass');\n } else {\n for (const entName of identifierEntities) {\n txLines.push(\n ` ${entName}: _NamespaceBuilder[_${className(entName)}Chunk]`,\n );\n }\n }\n\n const stdlibImports = ['from typing import Any, Generic, TypedDict, TypeVar'];\n if (usesDatetime) stdlibImports.unshift('from datetime import datetime');\n\n return [\n PY_HEADER +\n '\"\"\"Tx builder typing stub. Applied via `Instant(schema=...)`.\"\"\"',\n '',\n 'from __future__ import annotations',\n '',\n stdlibImports.join('\\n'),\n '',\n '',\n 'ChunkT = TypeVar(\"ChunkT\")',\n '',\n '',\n perEntityBlocks.join('\\n\\n\\n'),\n '',\n '',\n builderBlock,\n '',\n '',\n txLines.join('\\n'),\n '',\n ].join('\\n');\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "instant-cli",
3
3
  "type": "module",
4
- "version": "1.0.40-branch-python-sdk-v1.26482536960.1",
4
+ "version": "1.0.40-branch-python-sdk-v1.26483086955.1",
5
5
  "description": "Instant's CLI",
6
6
  "license": "Apache-2.0",
7
7
  "homepage": "https://github.com/instantdb/instant/tree/main/client/packages/cli",
@@ -50,9 +50,9 @@
50
50
  "strip-ansi": "^7.1.2",
51
51
  "supports-hyperlinks": "^4.4.0",
52
52
  "unconfig": "^7.5.0",
53
- "@instantdb/core": "1.0.40-branch-python-sdk-v1.26482536960.1",
54
- "@instantdb/platform": "1.0.40-branch-python-sdk-v1.26482536960.1",
55
- "@instantdb/version": "1.0.40-branch-python-sdk-v1.26482536960.1"
53
+ "@instantdb/core": "1.0.40-branch-python-sdk-v1.26483086955.1",
54
+ "@instantdb/platform": "1.0.40-branch-python-sdk-v1.26483086955.1",
55
+ "@instantdb/version": "1.0.40-branch-python-sdk-v1.26483086955.1"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@babel/core": "^7.17.9",
@@ -42,10 +42,14 @@ export const genpyCommand = ({ outDir }: { outDir?: string }) =>
42
42
  // Default: write alongside the schema file. `--out-dir` overrides for
43
43
  // monorepos where Python lives elsewhere, or for our own sandbox where
44
44
  // the schema is shared with the JS CLI tests.
45
- const targetDir = outDir ? path.resolve(outDir) : path.dirname(localSchemaFile.path);
45
+ const targetDir = outDir
46
+ ? path.resolve(outDir)
47
+ : path.dirname(localSchemaFile.path);
46
48
  yield* fs.makeDirectory(targetDir, { recursive: true }).pipe(
47
49
  Effect.mapError((e) =>
48
- GenpyWriteError.make({ message: `Failed to create ${targetDir}: ${e}` }),
50
+ GenpyWriteError.make({
51
+ message: `Failed to create ${targetDir}: ${e}`,
52
+ }),
49
53
  ),
50
54
  );
51
55
  const pyPath = path.join(targetDir, 'instant_types.py');
@@ -53,16 +57,20 @@ export const genpyCommand = ({ outDir }: { outDir?: string }) =>
53
57
 
54
58
  const pyContent = buildEntityModelsPy(localSchemaFile.schema);
55
59
  const pyiContent = buildTxStubPyi(localSchemaFile.schema);
56
- yield* fs.writeFileString(pyPath, pyContent).pipe(
57
- Effect.mapError((e) =>
58
- GenpyWriteError.make({ message: `Failed to write ${pyPath}: ${e}` }),
59
- ),
60
- );
61
- yield* fs.writeFileString(pyiPath, pyiContent).pipe(
62
- Effect.mapError((e) =>
63
- GenpyWriteError.make({ message: `Failed to write ${pyiPath}: ${e}` }),
64
- ),
65
- );
60
+ yield* fs
61
+ .writeFileString(pyPath, pyContent)
62
+ .pipe(
63
+ Effect.mapError((e) =>
64
+ GenpyWriteError.make({ message: `Failed to write ${pyPath}: ${e}` }),
65
+ ),
66
+ );
67
+ yield* fs
68
+ .writeFileString(pyiPath, pyiContent)
69
+ .pipe(
70
+ Effect.mapError((e) =>
71
+ GenpyWriteError.make({ message: `Failed to write ${pyiPath}: ${e}` }),
72
+ ),
73
+ );
66
74
 
67
75
  yield* Effect.log(`✅ Wrote ${pyPath} and ${pyiPath}`);
68
76
  });
@@ -206,7 +214,8 @@ export function buildEntityModelsPy(schema: SchemaLike): string {
206
214
  if (usesDatetime) stdlibImports.push('from datetime import datetime');
207
215
  stdlibImports.push(`from typing import ${typingImports.join(', ')}`);
208
216
  const importBlock =
209
- stdlibImports.join('\n') + '\n\n' +
217
+ stdlibImports.join('\n') +
218
+ '\n\n' +
210
219
  'from pydantic import BaseModel, ConfigDict';
211
220
 
212
221
  // Add record-model rebuilds so forward-string annotations to entity
@@ -222,7 +231,9 @@ export function buildEntityModelsPy(schema: SchemaLike): string {
222
231
  // Registry consumed by `Instant(schema=schema)`.
223
232
  const entityMapLines = [' "entities": {'];
224
233
  for (const entName of entityNames) {
225
- entityMapLines.push(` ${JSON.stringify(entName)}: ${className(entName)},`);
234
+ entityMapLines.push(
235
+ ` ${JSON.stringify(entName)}: ${className(entName)},`,
236
+ );
226
237
  }
227
238
  entityMapLines.push(' },');
228
239
  const recordMapLines = [' "records": {'];
@@ -334,9 +345,15 @@ function buildWebhookSection(
334
345
  const rootUnionTerms = entityNames.map((n) => `${className(n)}Record`);
335
346
  const rootUnion = `WebhookRecord = ${rootUnionTerms.join(' | ')}`;
336
347
 
337
- const handlerDictLines = ['WebhookHandlers = TypedDict(', ' "WebhookHandlers",', ' {'];
348
+ const handlerDictLines = [
349
+ 'WebhookHandlers = TypedDict(',
350
+ ' "WebhookHandlers",',
351
+ ' {',
352
+ ];
338
353
  for (const entName of entityNames) {
339
- handlerDictLines.push(` ${JSON.stringify(entName)}: _${className(entName)}Handlers,`);
354
+ handlerDictLines.push(
355
+ ` ${JSON.stringify(entName)}: _${className(entName)}Handlers,`,
356
+ );
340
357
  }
341
358
  handlerDictLines.push(` "$default": Callable[[WebhookRecord], Any],`);
342
359
  handlerDictLines.push(' },', ' total=False,', ')');
@@ -442,7 +459,9 @@ export function buildTxStubPyi(schema: SchemaLike): string {
442
459
  txLines.push(' pass');
443
460
  } else {
444
461
  for (const entName of identifierEntities) {
445
- txLines.push(` ${entName}: _NamespaceBuilder[_${className(entName)}Chunk]`);
462
+ txLines.push(
463
+ ` ${entName}: _NamespaceBuilder[_${className(entName)}Chunk]`,
464
+ );
446
465
  }
447
466
  }
448
467
 
@@ -450,7 +469,8 @@ export function buildTxStubPyi(schema: SchemaLike): string {
450
469
  if (usesDatetime) stdlibImports.unshift('from datetime import datetime');
451
470
 
452
471
  return [
453
- PY_HEADER + '"""Tx builder typing stub. Applied via `Instant(schema=...)`."""',
472
+ PY_HEADER +
473
+ '"""Tx builder typing stub. Applied via `Instant(schema=...)`."""',
454
474
  '',
455
475
  'from __future__ import annotations',
456
476
  '',