(options: Options)
| 76 | } |
| 77 | |
| 78 | export async function run(options: Options) { |
| 79 | // Resolve public key: CLI arg takes precedence, then ZENSTACK_STUDIO_AUTH_KEY env var. |
| 80 | options = { ...options, studioAuthKey: options.studioAuthKey ?? process.env['ZENSTACK_STUDIO_AUTH_KEY'] }; |
| 81 | if (!options.studioAuthKey) { |
| 82 | console.warn( |
| 83 | colors.yellow( |
| 84 | 'Warning: This proxy has no authentication. Do not expose it to the public network.\n' + |
| 85 | 'To secure it, get an API key from ZenStack Studio and set it via the ZENSTACK_STUDIO_AUTH_KEY environment variable.', |
| 86 | ), |
| 87 | ); |
| 88 | } |
| 89 | |
| 90 | const allowedLogLevels = ['error', 'query'] as const; |
| 91 | const log = options.logLevel?.filter((level): level is (typeof allowedLogLevels)[number] => |
| 92 | allowedLogLevels.includes(level as any), |
| 93 | ); |
| 94 | const schemaFile = getSchemaFile(options.schema); |
| 95 | console.log(colors.gray(`Loading ZModel schema from: ${schemaFile}`)); |
| 96 | |
| 97 | let outputPath = getOutputPath(options, schemaFile); |
| 98 | |
| 99 | // Ensure outputPath is absolute |
| 100 | if (!path.isAbsolute(outputPath)) { |
| 101 | outputPath = path.resolve(process.cwd(), outputPath); |
| 102 | } |
| 103 | |
| 104 | const model = await loadSchemaDocument(schemaFile); |
| 105 | |
| 106 | const dataSource = model.declarations.find(isDataSource); |
| 107 | |
| 108 | let databaseUrl = options.databaseUrl; |
| 109 | |
| 110 | if (!databaseUrl) { |
| 111 | const schemaUrl = dataSource?.fields.find((f) => f.name === 'url')?.value; |
| 112 | if (!schemaUrl) { |
| 113 | throw new CliError( |
| 114 | `The schema's "datasource" does not have a "url" field, please provide it with -d option.`, |
| 115 | ); |
| 116 | } |
| 117 | databaseUrl = evaluateUrl(schemaUrl); |
| 118 | } |
| 119 | |
| 120 | const provider = getStringLiteral(dataSource?.fields.find((f) => f.name === 'provider')?.value)!; |
| 121 | |
| 122 | const dialect = await createDialect(provider, databaseUrl!, outputPath); |
| 123 | |
| 124 | const fileUrl = typeof __filename !== 'undefined' ? __filename : import.meta.url; |
| 125 | |
| 126 | const jiti = createJiti(fileUrl); |
| 127 | |
| 128 | const schemaModule = (await jiti.import(path.join(outputPath, 'schema'))) as any; |
| 129 | |
| 130 | // Build omit configuration for computed fields and Unsupported fields. |
| 131 | const schema = schemaModule.schema as SchemaDef; |
| 132 | const omit: Record<string, Record<string, boolean>> = {}; |
| 133 | for (const [modelName, modelDef] of Object.entries(schema.models)) { |
| 134 | const omitFields: Record<string, boolean> = {}; |
| 135 | for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) { |
nothing calls this directly
no test coverage detected