UNPKG

convex

Version:

Client for the Convex Cloud

598 lines (597 loc) 19.8 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var codegen_exports = {}; __export(codegen_exports, { doCodegen: () => doCodegen, doFinalComponentCodegen: () => doFinalComponentCodegen, doInitConvexFolder: () => doInitConvexFolder, doInitialComponentCodegen: () => doInitialComponentCodegen, isPublishedPackage: () => isPublishedPackage }); module.exports = __toCommonJS(codegen_exports); var import_path = __toESM(require("path"), 1); var import_prettier = __toESM(require("prettier"), 1); var import_fs = require("../../bundler/fs.js"); var import_bundler = require("../../bundler/index.js"); var import_api = require("../codegen_templates/api.js"); var import_api_cjs = require("../codegen_templates/api_cjs.js"); var import_dataModel = require("../codegen_templates/dataModel.js"); var import_readme = require("../codegen_templates/readme.js"); var import_server = require("../codegen_templates/server.js"); var import_tsconfig = require("../codegen_templates/tsconfig.js"); var import_log = require("../../bundler/log.js"); var import_typecheck = require("./typecheck.js"); var import_config = require("./config.js"); var import_fsUtils = require("./fsUtils.js"); var import_component_server = require("../codegen_templates/component_server.js"); var import_component_api = require("../codegen_templates/component_api.js"); var import_utils = require("./utils/utils.js"); async function doInitConvexFolder(ctx, functionsFolder, opts) { const skipIfExists = false; let folder; if (functionsFolder) { folder = functionsFolder; } else { const { projectConfig, configPath } = await (0, import_config.readProjectConfig)(ctx); folder = (0, import_utils.functionsDir)(configPath, projectConfig); } await prepareForCodegen(ctx, folder, opts); await (0, import_fs.withTmpDir)(async (tmpDir) => { await doReadmeCodegen(ctx, tmpDir, folder, skipIfExists, opts); await doTsconfigCodegen(ctx, tmpDir, folder, skipIfExists, opts); }); } async function prepareForCodegen(ctx, functionsDir2, opts) { const legacyCodegenPath = import_path.default.join(functionsDir2, "_generated.ts"); if (ctx.fs.exists(legacyCodegenPath)) { if (opts?.dryRun) { (0, import_log.logError)( `Command would delete legacy codegen file: ${legacyCodegenPath}}` ); } else { (0, import_log.logError)(`Deleting legacy codegen file: ${legacyCodegenPath}}`); ctx.fs.unlink(legacyCodegenPath); } } const codegenDir = import_path.default.join(functionsDir2, "_generated"); ctx.fs.mkdir(codegenDir, { allowExisting: true, recursive: true }); return codegenDir; } async function doCodegen(ctx, functionsDir2, typeCheckMode, opts) { const { projectConfig } = await (0, import_config.readProjectConfig)(ctx); const codegenDir = await prepareForCodegen(ctx, functionsDir2, opts); await (0, import_fs.withTmpDir)(async (tmpDir) => { const writtenFiles = []; const useTypeScript = (0, import_config.usesTypeScriptCodegen)(projectConfig); const generateCommonJSApi = opts?.generateCommonJSApi || projectConfig.generateCommonJSApi; const schemaFiles = await doDataModelCodegen( ctx, tmpDir, functionsDir2, codegenDir, useTypeScript, opts ); writtenFiles.push(...schemaFiles); const serverFiles = await writeServerFiles( ctx, tmpDir, codegenDir, useTypeScript, opts ); writtenFiles.push(...serverFiles); const apiFiles = await doApiCodegen( ctx, tmpDir, functionsDir2, codegenDir, useTypeScript, generateCommonJSApi, opts ); writtenFiles.push(...apiFiles); if (!opts?.debug) { for (const file of ctx.fs.listDir(codegenDir)) { if (!writtenFiles.includes(file.name)) { (0, import_fsUtils.recursivelyDelete)(ctx, import_path.default.join(codegenDir, file.name), opts); } } } await (0, import_typecheck.typeCheckFunctionsInMode)(ctx, typeCheckMode, functionsDir2); }); } async function doInitialComponentCodegen(ctx, tmpDir, componentDirectory, opts) { const { projectConfig } = await (0, import_config.readProjectConfig)(ctx); if (isPublishedPackage(componentDirectory)) { if (opts?.verbose) { (0, import_log.logMessage)( `skipping initial codegen for installed package ${componentDirectory.path}` ); } return; } const codegenDir = await prepareForCodegen( ctx, componentDirectory.path, opts ); const writtenFiles = []; const useTypeScript = !componentDirectory.isRoot || (0, import_config.usesTypeScriptCodegen)(projectConfig); const generateCommonJSApi = opts?.generateCommonJSApi || projectConfig.generateCommonJSApi; const dataModelFiles = await doInitialComponentDataModelCodegen( ctx, tmpDir, componentDirectory, codegenDir, useTypeScript, opts ); writtenFiles.push(...dataModelFiles); const serverFiles = await doInitialComponentServerCodegen( ctx, componentDirectory.isRoot, tmpDir, codegenDir, useTypeScript, opts ); writtenFiles.push(...serverFiles); const apiFiles = await doInitialComponentApiCodegen( ctx, componentDirectory.isRoot, tmpDir, codegenDir, useTypeScript, generateCommonJSApi, opts ); writtenFiles.push(...apiFiles); if (!componentDirectory.isRoot) { const componentTSPath = import_path.default.join(codegenDir, "component.ts"); if (ctx.fs.exists(componentTSPath)) { writtenFiles.push("component.ts"); } } if (!opts?.debug) { for (const file of ctx.fs.listDir(codegenDir)) { if (!writtenFiles.includes(file.name)) { (0, import_fsUtils.recursivelyDelete)(ctx, import_path.default.join(codegenDir, file.name), opts); } } } } function isPublishedPackage(componentDirectory) { return componentDirectory.definitionPath.endsWith(".js") && !componentDirectory.isRoot; } async function doFinalComponentCodegen(ctx, tmpDir, rootComponent, componentDirectory, startPushResponse, componentsMap, opts) { const { projectConfig } = await (0, import_config.readProjectConfig)(ctx); const isPublishedPackage2 = componentDirectory.definitionPath.endsWith(".js") && !componentDirectory.isRoot; if (isPublishedPackage2) { return; } const codegenDir = import_path.default.join(componentDirectory.path, "_generated"); ctx.fs.mkdir(codegenDir, { allowExisting: true, recursive: true }); const useTypeScript = !componentDirectory.isRoot || (0, import_config.usesTypeScriptCodegen)(projectConfig); const hasSchemaFile = schemaFileExists(ctx, componentDirectory.path); let dataModelContents; if (hasSchemaFile) { if (projectConfig.codegen.staticDataModel) { dataModelContents = useTypeScript ? await (0, import_dataModel.staticDataModelTS)( ctx, startPushResponse, rootComponent, componentDirectory ) : await (0, import_dataModel.staticDataModelDTS)( ctx, startPushResponse, rootComponent, componentDirectory ); } else { dataModelContents = useTypeScript ? (0, import_dataModel.dynamicDataModelTS)() : (0, import_dataModel.dynamicDataModelDTS)(); } } else { dataModelContents = useTypeScript ? (0, import_dataModel.noSchemaDataModelTS)() : (0, import_dataModel.noSchemaDataModelDTS)(); } const dataModelPath = import_path.default.join( codegenDir, useTypeScript ? "dataModel.ts" : "dataModel.d.ts" ); await writeFormattedFile( ctx, tmpDir, dataModelContents, "typescript", dataModelPath, opts ); if (!componentDirectory.isRoot) { const componentTSPath = import_path.default.join(codegenDir, "component.ts"); const componentTSContents = await (0, import_component_api.componentTS)( ctx, startPushResponse, rootComponent, componentDirectory ); await writeFormattedFile( ctx, tmpDir, componentTSContents, "typescript", componentTSPath, opts ); } await writeServerFilesForComponent( ctx, componentDirectory.isRoot, tmpDir, codegenDir, useTypeScript, opts ); if (!useTypeScript) { const apiDTSPath = import_path.default.join(codegenDir, "api.d.ts"); const apiContents = await (0, import_component_api.componentApiDTS)( ctx, startPushResponse, rootComponent, componentDirectory, componentsMap, { staticApi: projectConfig.codegen.staticApi, useComponentApiImports: (0, import_config.usesComponentApiImports)(projectConfig) } ); await writeFormattedFile( ctx, tmpDir, apiContents, "typescript", apiDTSPath, opts ); if (opts?.generateCommonJSApi || projectConfig.generateCommonJSApi) { const apiCjsDTSPath = import_path.default.join(codegenDir, "api_cjs.d.cts"); await writeFormattedFile( ctx, tmpDir, apiContents, "typescript", apiCjsDTSPath, opts ); } } else { const apiTSPath = import_path.default.join(codegenDir, "api.ts"); const apiContents = await (0, import_component_api.componentApiTSWithTypes)( ctx, startPushResponse, rootComponent, componentDirectory, componentsMap, { staticApi: projectConfig.codegen.staticApi, useComponentApiImports: (0, import_config.usesComponentApiImports)(projectConfig) } ); await writeFormattedFile( ctx, tmpDir, apiContents, "typescript", apiTSPath, opts ); } } async function doReadmeCodegen(ctx, tmpDir, functionsDir2, skipIfExists, opts) { const readmePath = import_path.default.join(functionsDir2, "README.md"); if (skipIfExists && ctx.fs.exists(readmePath)) { (0, import_log.logVerbose)(`Not overwriting README.md.`); return; } await writeFormattedFile( ctx, tmpDir, (0, import_readme.readmeCodegen)(), "markdown", readmePath, opts ); } async function doTsconfigCodegen(ctx, tmpDir, functionsDir2, skipIfExists, opts) { const tsconfigPath = import_path.default.join(functionsDir2, "tsconfig.json"); if (skipIfExists && ctx.fs.exists(tsconfigPath)) { (0, import_log.logVerbose)(`Not overwriting tsconfig.json.`); return; } await writeFormattedFile( ctx, tmpDir, (0, import_tsconfig.tsconfigCodegen)(), "json", tsconfigPath, opts ); } function schemaFileExists(ctx, functionsDir2) { let schemaPath = import_path.default.join(functionsDir2, "schema.ts"); let hasSchemaFile = ctx.fs.exists(schemaPath); if (!hasSchemaFile) { schemaPath = import_path.default.join(functionsDir2, "schema.js"); hasSchemaFile = ctx.fs.exists(schemaPath); } return hasSchemaFile; } async function doDataModelCodegen(ctx, tmpDir, functionsDir2, codegenDir, useTypeScript, opts) { const hasSchemaFile = schemaFileExists(ctx, functionsDir2); const schemaContent = hasSchemaFile ? useTypeScript ? (0, import_dataModel.dynamicDataModelTS)() : (0, import_dataModel.dynamicDataModelDTS)() : useTypeScript ? (0, import_dataModel.noSchemaDataModelTS)() : (0, import_dataModel.noSchemaDataModelDTS)(); const filename = useTypeScript ? "dataModel.ts" : "dataModel.d.ts"; await writeFormattedFile( ctx, tmpDir, schemaContent, "typescript", import_path.default.join(codegenDir, filename), opts ); return [filename]; } async function writeServerFiles(ctx, tmpDir, codegenDir, useTypeScript, opts) { if (!useTypeScript) { const serverContent = (0, import_server.serverCodegen)({ useTypeScript: false }); await writeFormattedFile( ctx, tmpDir, serverContent.JS, "typescript", import_path.default.join(codegenDir, "server.js"), opts ); await writeFormattedFile( ctx, tmpDir, serverContent.DTS, "typescript", import_path.default.join(codegenDir, "server.d.ts"), opts ); return ["server.js", "server.d.ts"]; } else { const serverContent = (0, import_server.serverCodegen)({ useTypeScript: true }); await writeFormattedFile( ctx, tmpDir, serverContent.TS, "typescript", import_path.default.join(codegenDir, "server.ts"), opts ); return ["server.ts"]; } } async function writeComponentServerFile(ctx, tmpDir, codegenDir, opts) { const serverTSPath = import_path.default.join(codegenDir, "server.ts"); const serverTSContents = (0, import_component_server.componentServerTS)(false); await writeFormattedFile( ctx, tmpDir, serverTSContents, "typescript", serverTSPath, opts ); return ["server.ts"]; } async function writeServerFilesForComponent(ctx, isRoot, tmpDir, codegenDir, useTypeScript, opts) { if (isRoot) { return await writeServerFiles(ctx, tmpDir, codegenDir, useTypeScript, opts); } else { return await writeComponentServerFile(ctx, tmpDir, codegenDir, opts); } } async function doInitialComponentServerCodegen(ctx, isRoot, tmpDir, codegenDir, useTypeScript, opts) { return await writeServerFilesForComponent( ctx, isRoot, tmpDir, codegenDir, useTypeScript, opts ); } async function doInitialComponentDataModelCodegen(ctx, tmpDir, componentDirectory, codegenDir, useTypeScript, opts) { const hasSchemaFile = schemaFileExists(ctx, componentDirectory.path); const dataModelContent = hasSchemaFile ? useTypeScript ? (0, import_dataModel.dynamicDataModelTS)() : (0, import_dataModel.dynamicDataModelDTS)() : useTypeScript ? (0, import_dataModel.noSchemaDataModelTS)() : (0, import_dataModel.noSchemaDataModelDTS)(); const filename = useTypeScript ? "dataModel.ts" : "dataModel.d.ts"; const dataModelPath = import_path.default.join(codegenDir, filename); if (!ctx.fs.exists(dataModelPath)) { await writeFormattedFile( ctx, tmpDir, dataModelContent, "typescript", dataModelPath, opts ); } return [filename]; } async function doInitialComponentApiCodegen(ctx, isRoot, tmpDir, codegenDir, useTypeScript, generateCommonJSApi, opts) { const writtenFiles = []; if (!useTypeScript) { const apiJS = (0, import_component_api.componentApiJs)(); await writeFormattedFile( ctx, tmpDir, apiJS, "typescript", import_path.default.join(codegenDir, "api.js"), opts ); const apiDTSPath = import_path.default.join(codegenDir, "api.d.ts"); const apiStubDTS = (0, import_component_api.componentApiStubDTS)(); if (!ctx.fs.exists(apiDTSPath)) { await writeFormattedFile( ctx, tmpDir, apiStubDTS, "typescript", apiDTSPath, opts ); } writtenFiles.push("api.js", "api.d.ts"); if (generateCommonJSApi && isRoot) { const apiCjsJS = (0, import_component_api.rootComponentApiCJS)(); await writeFormattedFile( ctx, tmpDir, apiCjsJS, "typescript", import_path.default.join(codegenDir, "api_cjs.cjs"), opts ); const cjsStubPath = import_path.default.join(codegenDir, "api_cjs.d.cts"); if (!ctx.fs.exists(cjsStubPath)) { await writeFormattedFile( ctx, tmpDir, apiStubDTS, "typescript", cjsStubPath, opts ); } writtenFiles.push("api_cjs.cjs", "api_cjs.d.cts"); } } else { const apiTSPath = import_path.default.join(codegenDir, "api.ts"); const apiTS = (0, import_component_api.componentApiStubTS)(); if (!ctx.fs.exists(apiTSPath)) { await writeFormattedFile( ctx, tmpDir, apiTS, "typescript", apiTSPath, opts ); } writtenFiles.push("api.ts"); } return writtenFiles; } async function doApiCodegen(ctx, tmpDir, functionsDir2, codegenDir, useTypeScript, generateCommonJSApi, opts) { const absModulePaths = await (0, import_bundler.entryPoints)(ctx, functionsDir2); const modulePaths = absModulePaths.map((p) => import_path.default.relative(functionsDir2, p)).sort(); const writtenFiles = []; if (!useTypeScript) { const apiContent = (0, import_api.apiCodegen)(modulePaths, { useTypeScript: false }); await writeFormattedFile( ctx, tmpDir, apiContent.JS, "typescript", import_path.default.join(codegenDir, "api.js"), opts ); await writeFormattedFile( ctx, tmpDir, apiContent.DTS, "typescript", import_path.default.join(codegenDir, "api.d.ts"), opts ); writtenFiles.push("api.js", "api.d.ts"); if (generateCommonJSApi) { const apiCjsContent = (0, import_api_cjs.apiCjsCodegen)(modulePaths); await writeFormattedFile( ctx, tmpDir, apiCjsContent.JS, "typescript", import_path.default.join(codegenDir, "api_cjs.cjs"), opts ); await writeFormattedFile( ctx, tmpDir, apiCjsContent.DTS, "typescript", import_path.default.join(codegenDir, "api_cjs.d.cts"), opts ); writtenFiles.push("api_cjs.cjs", "api_cjs.d.cts"); } } else { const apiContent = (0, import_api.apiCodegen)(modulePaths, { useTypeScript: true }); await writeFormattedFile( ctx, tmpDir, apiContent.TS, "typescript", import_path.default.join(codegenDir, "api.ts"), opts ); writtenFiles.push("api.ts"); } return writtenFiles; } async function writeFormattedFile(ctx, tmpDir, contents, filetype, destination, options) { const formattedContents = await import_prettier.default.format(contents, { parser: filetype, pluginSearchDirs: false }); if (options?.debug) { (0, import_log.logOutput)(`# ${import_path.default.resolve(destination)}`); (0, import_log.logOutput)(formattedContents); return; } try { const existing = ctx.fs.readUtf8File(destination); if (existing === formattedContents) { return; } } catch (err) { if (err.code !== "ENOENT") { throw err; } } if (options?.dryRun) { (0, import_log.logOutput)(`Command would write file: ${destination}`); return; } const tmpPath = tmpDir.writeUtf8File(formattedContents); ctx.fs.swapTmpFile(tmpPath, destination); } //# sourceMappingURL=codegen.js.map