@platforma-sdk/tengo-builder 2.5.6 → 2.5.8
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/dist/_virtual/_rolldown/runtime.cjs +7 -13
- package/dist/commands/build.cjs +5 -6
- package/dist/commands/build.cjs.map +1 -1
- package/dist/commands/build.d.ts +5 -5
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +1 -2
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/check.cjs +6 -7
- package/dist/commands/check.cjs.map +1 -1
- package/dist/commands/check.d.ts +2 -2
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +1 -2
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/dump/artifacts.cjs +5 -6
- package/dist/commands/dump/artifacts.cjs.map +1 -1
- package/dist/commands/dump/artifacts.d.ts +3 -3
- package/dist/commands/dump/artifacts.d.ts.map +1 -0
- package/dist/commands/dump/artifacts.js +1 -2
- package/dist/commands/dump/artifacts.js.map +1 -1
- package/dist/commands/dump/software.cjs +5 -6
- package/dist/commands/dump/software.cjs.map +1 -1
- package/dist/commands/dump/software.d.ts +2 -2
- package/dist/commands/dump/software.d.ts.map +1 -0
- package/dist/commands/dump/software.js +1 -2
- package/dist/commands/dump/software.js.map +1 -1
- package/dist/commands/test.cjs +6 -7
- package/dist/commands/test.cjs.map +1 -1
- package/dist/commands/test.d.ts +2 -2
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +1 -2
- package/dist/commands/test.js.map +1 -1
- package/dist/compiler/artifactset.cjs +3 -4
- package/dist/compiler/artifactset.cjs.map +1 -1
- package/dist/compiler/artifactset.js +1 -2
- package/dist/compiler/artifactset.js.map +1 -1
- package/dist/compiler/compiler.cjs +6 -7
- package/dist/compiler/compiler.cjs.map +1 -1
- package/dist/compiler/compiler.js +1 -2
- package/dist/compiler/compiler.js.map +1 -1
- package/dist/compiler/compileroptions.cjs +2 -3
- package/dist/compiler/compileroptions.cjs.map +1 -1
- package/dist/compiler/compileroptions.js +1 -2
- package/dist/compiler/compileroptions.js.map +1 -1
- package/dist/compiler/main.cjs +7 -8
- package/dist/compiler/main.cjs.map +1 -1
- package/dist/compiler/main.js +1 -2
- package/dist/compiler/main.js.map +1 -1
- package/dist/compiler/package.cjs +1 -2
- package/dist/compiler/package.cjs.map +1 -1
- package/dist/compiler/package.js +1 -1
- package/dist/compiler/source.cjs +4 -5
- package/dist/compiler/source.cjs.map +1 -1
- package/dist/compiler/source.js +1 -2
- package/dist/compiler/source.js.map +1 -1
- package/dist/compiler/template.cjs +3 -4
- package/dist/compiler/template.cjs.map +1 -1
- package/dist/compiler/template.js +2 -3
- package/dist/compiler/template.js.map +1 -1
- package/dist/compiler/util.cjs +2 -3
- package/dist/compiler/util.cjs.map +1 -1
- package/dist/compiler/util.js +1 -2
- package/dist/compiler/util.js.map +1 -1
- package/dist/index.cjs +7 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/shared/basecmd.cjs +2 -3
- package/dist/shared/basecmd.cjs.map +1 -1
- package/dist/shared/basecmd.js +1 -2
- package/dist/shared/basecmd.js.map +1 -1
- package/dist/shared/dump.cjs +3 -4
- package/dist/shared/dump.cjs.map +1 -1
- package/dist/shared/dump.js +1 -2
- package/dist/shared/dump.js.map +1 -1
- package/dist/shared/proc.cjs +2 -3
- package/dist/shared/proc.cjs.map +1 -1
- package/dist/shared/proc.js +1 -2
- package/dist/shared/proc.js.map +1 -1
- package/package.json +9 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","names":[],"sources":["../../src/compiler/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport * as path from \"node:path\";\nimport * as fs from \"node:fs\";\nimport { pathType } from \"./util\";\nimport type { TemplatesAndLibs } from \"./compiler\";\nimport { TengoTemplateCompiler } from \"./compiler\";\nimport { getSha256 } from \"./source\";\nimport type { CompileMode, FullArtifactName } from \"./package\";\nimport { fullNameToString, typedArtifactNameToString } from \"./package\";\nimport { ArtifactSource, parseSourceFile } from \"./source\";\nimport { newTemplateFromContent, templateToSource } from \"./template\";\nimport type winston from \"winston\";\nimport { tryResolve, tryResolveOrError } from \"@milaboratories/resolve-helper\";\nimport { serializeTemplate } from \"@milaboratories/pl-model-backend\";\n\ninterface PackageId {\n /** Package name from package.json */\n readonly name: string;\n /** Package version from package.json */\n readonly version: string;\n}\n\ninterface PackageInfo extends PackageId {\n /** Package type from package.json */\n readonly type: string | undefined;\n /** Path to package root */\n readonly root: string;\n /** Context of package info */\n readonly context: PackageInfoContext;\n /** Dependencies */\n readonly dependencies: PackageInfo[];\n}\n\ninterface PackageJson {\n name: string;\n version: string;\n type: string | undefined;\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n}\n\nconst compiledTplSuffix = \".plj.gz\";\nconst compiledLibSuffix = \".lib.tengo\";\nconst compiledSoftwareSuffix = \".sw.json\";\nconst compiledAssetSuffix = \".as.json\";\n\n// We need to keep track of dependencies for correct tgo-test CLI utility configuraiton.\n// It is much simpler to do this here, than duplicate all tle logic regarding dependencies\n// in go code.\nconst srcTestSuffix = \".test.tengo\";\n\nconst srcTplSuffix = \".tpl.tengo\";\nconst srcLibSuffix = \".lib.tengo\";\nconst srcSoftwareSuffix = \".sw.json\";\nconst srcAssetSuffix = \".as.json\";\nconst compilableSuffixes = [srcLibSuffix, srcTplSuffix, srcSoftwareSuffix, srcAssetSuffix];\n\n/**\n * Resolves path to package.json file of the given dependency package.\n */\nfunction resolvePackageJsonPackage(root: string, depPackageName: string): string | undefined {\n if (!path.isAbsolute(root)) {\n throw new Error(`Root path must be absolute: ${root}`);\n }\n\n // First approach: resolving package's main entry point and try to find package.json\n // in dir tree upwards.\n let resolved = tryResolve(root, depPackageName);\n if (resolved) {\n let depth = 0;\n do {\n const p = path.join(resolved, \"package.json\");\n if (pathType(p) === \"file\") return p;\n depth++;\n resolved = path.dirname(resolved);\n } while (depth < 7 && path.basename(resolved) !== \"node_modules\");\n }\n\n // Second approach: trying to find package.json in the package dir.\n const resolved2 = tryResolveOrError(root, `${depPackageName}/package.json`);\n if (resolved2.result === undefined) {\n if (resolved2.err === \"ERR_PACKAGE_PATH_NOT_EXPORTED\")\n // tolerating not-exported package.json for dev dependencies\n return undefined;\n throw new Error(\n `Can't resolve package.json for package ${depPackageName ?? \".\"} relative to ${root}`,\n );\n }\n return resolved2.result;\n}\n\nexport function resolvePackageJsonRoot(root: string): string {\n if (!path.isAbsolute(root)) {\n throw new Error(`Root path must be absolute: ${root}`);\n }\n\n const p = path.join(root, \"package.json\");\n if (pathType(p) === \"file\") return p;\n throw new Error(`Can't resolve package.json in ${root}`);\n}\n\ntype PackageInfoContext = \"root\" | \"dependency\" | \"devDependency\";\n\n/**\n * Get package info from package.json and all dependencies.\n */\nexport function getPackageInfo(\n root: string,\n logger: winston.Logger,\n context: PackageInfoContext = \"root\",\n): PackageInfo {\n const packageJsonPath = resolvePackageJsonRoot(root);\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString()) as PackageJson;\n\n // resolving dependencies\n const depInfos: PackageInfo[] = [];\n\n if (packageJson.dependencies && context !== \"devDependency\") {\n for (const dep of Object.keys(packageJson.dependencies)) {\n const depPackageJson = resolvePackageJsonPackage(root, dep);\n if (depPackageJson === undefined)\n throw new Error(`Can't resolve package.json for dependency ${dep} of ${root}`);\n const depRoot = path.dirname(depPackageJson);\n depInfos.push(getPackageInfo(depRoot, logger, \"dependency\"));\n }\n }\n\n if (packageJson.devDependencies && context === \"root\") {\n for (const dep of Object.keys(packageJson.devDependencies)) {\n const depPackageJson = resolvePackageJsonPackage(root, dep);\n if (depPackageJson === undefined) {\n logger.warn(`Can't resolve package.json for dev dependency ${dep} of ${root}`);\n // tolerating not-exported package.json for dev dependencies\n continue;\n }\n const depRoot = path.dirname(depPackageJson);\n depInfos.push(getPackageInfo(depRoot, logger, \"devDependency\"));\n }\n }\n\n return {\n name: packageJson.name,\n version: packageJson.version,\n type: packageJson.type,\n dependencies: depInfos,\n root,\n context,\n };\n}\n\nfunction resolveLibsDst(mode: CompileMode, root: string) {\n return path.resolve(root, mode, \"tengo\", \"lib\");\n}\n\nfunction resolveTemplatesDst(mode: CompileMode, root: string) {\n return path.resolve(root, mode, \"tengo\", \"tpl\");\n}\n\nfunction resolveSoftwareDst(mode: CompileMode, root: string) {\n return path.resolve(root, mode, \"tengo\", \"software\");\n}\n\nfunction resolveAssetsDst(mode: CompileMode, root: string) {\n return path.resolve(root, mode, \"tengo\", \"asset\");\n}\n\nfunction loadDependencies(\n logger: winston.Logger,\n compiler: TengoTemplateCompiler,\n packageInfo: PackageInfo,\n): void {\n for (const dep of packageInfo.dependencies) loadDependencies(logger, compiler, dep);\n\n if (packageInfo.context === \"root\")\n // we are not reading compiled files for root package\n return;\n\n // we are in package folder\n const libDistFolder = resolveLibsDst(\"dist\", packageInfo.root);\n const tplDistFolder = resolveTemplatesDst(\"dist\", packageInfo.root);\n const softwareDistFolder = resolveSoftwareDst(\"dist\", packageInfo.root);\n const assetDistFolder = resolveAssetsDst(\"dist\", packageInfo.root);\n\n const libDistExists = pathType(libDistFolder) === \"dir\";\n const tplDistExists = pathType(tplDistFolder) === \"dir\";\n const softwareDistExists = pathType(softwareDistFolder) === \"dir\";\n const assetDistExists = pathType(assetDistFolder) === \"dir\";\n\n if (!libDistExists && !tplDistExists && !softwareDistExists && !assetDistExists)\n // if neither of tengo-specific folders detected, skipping package\n return;\n\n const packageId = { name: packageInfo.name, version: packageInfo.version };\n\n if (libDistExists) {\n loadLibsFromDir(logger, packageId, \"dist\", libDistFolder, compiler);\n }\n\n if (tplDistExists) {\n loadTemplatesFromDir(logger, packageId, \"dist\", tplDistFolder, compiler);\n }\n\n if (softwareDistExists) {\n loadSoftwareFromDir(logger, packageId, \"dist\", softwareDistFolder, compiler);\n }\n\n if (assetDistExists) {\n loadAssetsFromDir(logger, packageId, \"dist\", assetDistFolder, compiler);\n }\n}\n\nfunction loadLibsFromDir(\n logger: winston.Logger,\n packageId: PackageId,\n mode: CompileMode,\n folder: string,\n compiler: TengoTemplateCompiler,\n) {\n for (const f of fs.readdirSync(folder)) {\n const file = path.resolve(folder, f);\n if (!f.endsWith(compiledLibSuffix)) throw new Error(`unexpected file in 'lib' folder: ${file}`);\n const fullName: FullArtifactName = {\n type: \"library\",\n pkg: packageId.name,\n id: f.slice(0, f.length - compiledLibSuffix.length),\n version: packageId.version,\n };\n const src = parseSourceFile(logger, mode, file, fullName, true);\n compiler.addLib(src);\n logger.debug(`Adding dependency ${fullNameToString(fullName)} from ${file}`);\n if (src.dependencies.length > 0) {\n logger.debug(\"Dependencies:\");\n for (const dep of src.dependencies) logger.debug(` - ${typedArtifactNameToString(dep)}`);\n }\n }\n}\n\nfunction loadTemplatesFromDir(\n logger: winston.Logger,\n packageId: PackageId,\n mode: CompileMode,\n folder: string,\n compiler: TengoTemplateCompiler,\n) {\n // adding templates\n for (const f of fs.readdirSync(folder)) {\n const file = path.resolve(folder, f);\n if (!f.endsWith(compiledTplSuffix)) throw new Error(`unexpected file in 'tpl' folder: ${file}`);\n const fullName: FullArtifactName = {\n type: \"template\",\n pkg: packageId.name,\n id: f.slice(0, f.length - compiledTplSuffix.length),\n version: packageId.version,\n };\n const tpl = newTemplateFromContent(mode, fullName, fs.readFileSync(file));\n compiler.addTemplate(templateToSource(tpl));\n logger.debug(`Adding dependency ${fullNameToString(fullName)} from ${file}`);\n }\n}\n\nfunction loadSoftwareFromDir(\n logger: winston.Logger,\n packageId: PackageId,\n mode: CompileMode,\n folder: string,\n compiler: TengoTemplateCompiler,\n) {\n for (const f of fs.readdirSync(folder)) {\n const file = path.resolve(folder, f);\n if (!f.endsWith(compiledSoftwareSuffix))\n throw new Error(`unexpected file in 'software' folder: ${file}`);\n const fullName: FullArtifactName = {\n type: \"software\",\n pkg: packageId.name,\n id: f.slice(0, f.length - compiledSoftwareSuffix.length),\n version: packageId.version,\n };\n\n const source = fs.readFileSync(file).toString();\n\n const software = new ArtifactSource(mode, fullName, getSha256(source), source, file, [], []);\n\n logger.debug(`Adding dependency ${fullNameToString(fullName)} from ${file}`);\n compiler.addSoftware(software);\n }\n}\n\nfunction loadAssetsFromDir(\n logger: winston.Logger,\n packageId: PackageId,\n mode: CompileMode,\n folder: string,\n compiler: TengoTemplateCompiler,\n) {\n for (const f of fs.readdirSync(folder)) {\n const file = path.resolve(folder, f);\n if (!f.endsWith(compiledAssetSuffix))\n throw new Error(`unexpected file in 'asset' folder: ${file}`);\n const fullName: FullArtifactName = {\n type: \"asset\",\n pkg: packageId.name,\n id: f.slice(0, f.length - compiledAssetSuffix.length),\n version: packageId.version,\n };\n\n const source = fs.readFileSync(file).toString();\n\n const asset = new ArtifactSource(mode, fullName, getSha256(source), source, file, [], []);\n\n logger.debug(`Adding dependency ${fullNameToString(fullName)} from ${file}`);\n compiler.addAsset(asset);\n }\n}\n\nexport function parseSources(\n logger: winston.Logger,\n packageId: PackageId,\n mode: CompileMode,\n root: string,\n subdir: string,\n): ArtifactSource[] {\n const sources: ArtifactSource[] = [];\n\n for (const f of fs.readdirSync(path.join(root, subdir))) {\n const inRootPath = path.join(subdir, f); // path to item inside given <root>\n const fullPath = path.join(root, inRootPath); // full path to item from CWD (or abs path, if <root> is abs path)\n\n if (pathType(fullPath) === \"dir\") {\n const nested = parseSources(logger, packageId, mode, root, inRootPath);\n sources.push(...nested);\n continue;\n }\n\n // Handling index.lib.tengo files: rename them to <package-name>.lib.tengo\n const artifactName =\n f === \"index.lib.tengo\" ? `${path.dirname(inRootPath)}.lib.tengo` : inRootPath;\n\n const fullName = fullNameFromFileName(packageId, artifactName.replaceAll(path.sep, \".\"));\n if (!fullName) {\n logger.info(`Skipping unknown file type: ${artifactName}`);\n continue; // skip unknown file types\n }\n\n // if (subdir != '') {\n // throw new Error(`Templates and libraries should reside only inside '${root}' dir.\n // You are free to have any file and dirs structure inside '${root}' keeping other files where you want,\n // but regarding ${compilableSuffixes.join(', ')}, the flat file structure is mandatory.`);\n // }\n\n const file = path.resolve(root, inRootPath);\n logger.debug(`Parsing ${fullNameToString(fullName)} from ${file}`);\n const newSrc = parseSourceFile(logger, mode, file, fullName, true);\n if (newSrc.dependencies.length > 0) {\n logger.debug(\"Detected dependencies:\");\n for (const dep of newSrc.dependencies) logger.debug(` - ${typedArtifactNameToString(dep)}`);\n }\n\n sources.push(newSrc);\n }\n\n return sources;\n}\n\nexport function newCompiler(\n logger: winston.Logger,\n packageInfo: PackageInfo,\n mode: CompileMode,\n): TengoTemplateCompiler {\n const compiler = new TengoTemplateCompiler(mode);\n\n // collect all data (templates, libs and software) from dependency tree\n loadDependencies(logger, compiler, packageInfo);\n\n return compiler;\n}\n\nexport function fullNameFromFileName(\n packageId: PackageId,\n artifactName: string,\n): FullArtifactName | null {\n const pkgAndVersion = { pkg: packageId.name, version: packageId.version };\n if (artifactName.endsWith(srcLibSuffix)) {\n return {\n ...pkgAndVersion,\n id: artifactName.substring(0, artifactName.length - srcLibSuffix.length),\n type: \"library\",\n };\n }\n\n if (artifactName.endsWith(srcTplSuffix)) {\n return {\n ...pkgAndVersion,\n id: artifactName.substring(0, artifactName.length - srcTplSuffix.length),\n type: \"template\",\n };\n }\n\n if (artifactName.endsWith(srcSoftwareSuffix)) {\n return {\n ...pkgAndVersion,\n id: artifactName.substring(0, artifactName.length - srcSoftwareSuffix.length),\n type: \"software\",\n };\n }\n\n if (artifactName.endsWith(srcAssetSuffix)) {\n return {\n ...pkgAndVersion,\n id: artifactName.substring(0, artifactName.length - srcAssetSuffix.length),\n type: \"asset\",\n };\n }\n\n if (artifactName.endsWith(srcTestSuffix)) {\n return {\n ...pkgAndVersion,\n id: artifactName.substring(0, artifactName.length - srcTestSuffix.length),\n type: \"test\",\n };\n }\n\n return null;\n}\n\nexport function compile(\n logger: winston.Logger,\n packageInfo: PackageInfo,\n mode: CompileMode,\n): TemplatesAndLibs {\n const compiler = newCompiler(logger, packageInfo, mode);\n const sources = parseSources(logger, packageInfo, mode, \"src\", \"\");\n\n // checking that we have something to do\n if (sources.length === 0) {\n const lookFor: string[] = [];\n for (const suffix of compilableSuffixes) {\n lookFor.push(`*${suffix}`);\n }\n\n logger.error(`Nothing to compile. Looked for ${lookFor.join(\", \")}`);\n process.exit(1);\n }\n\n // compilation\n logger.info(`Compiling '${mode}'...`);\n const compiled = compiler.compileAndAdd(sources);\n logger.debug(`Done.`);\n\n return compiled;\n}\n\nexport function savePacks(logger: winston.Logger, compiled: TemplatesAndLibs, mode: CompileMode) {\n // writing libs\n if (compiled.libs.length > 0) {\n const libOutput = resolveLibsDst(mode, \".\");\n fs.mkdirSync(libOutput, { recursive: true });\n for (const lib of compiled.libs) {\n const file = path.resolve(libOutput, lib.fullName.id + compiledLibSuffix);\n logger.info(` - writing ${file}`);\n fs.writeFileSync(file, lib.src);\n }\n }\n\n // writing templates\n if (compiled.templates.length > 0) {\n const tplOutput = resolveTemplatesDst(mode, \".\");\n fs.mkdirSync(tplOutput, { recursive: true });\n for (const tpl of compiled.templates) {\n const file = path.resolve(tplOutput, tpl.fullName.id + compiledTplSuffix);\n logger.info(` - writing ${file}`);\n fs.writeFileSync(file, serializeTemplate(tpl.data));\n }\n }\n\n // writing software\n if (compiled.software.length > 0) {\n const swOutput = resolveSoftwareDst(mode, \".\");\n fs.mkdirSync(swOutput, { recursive: true });\n for (const sw of compiled.software) {\n const file = path.resolve(swOutput, sw.fullName.id + compiledSoftwareSuffix);\n logger.info(` - writing ${file}`);\n fs.writeFileSync(file, sw.src);\n }\n }\n\n // writing assets\n if (compiled.assets.length > 0) {\n const swOutput = resolveAssetsDst(mode, \".\");\n fs.mkdirSync(swOutput, { recursive: true });\n for (const sw of compiled.software) {\n const file = path.resolve(swOutput, sw.fullName.id + compiledAssetSuffix);\n logger.info(` - writing ${file}`);\n fs.writeFileSync(file, sw.src);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"main.js","names":[],"sources":["../../src/compiler/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport * as path from \"node:path\";\nimport * as fs from \"node:fs\";\nimport { pathType } from \"./util\";\nimport type { TemplatesAndLibs } from \"./compiler\";\nimport { TengoTemplateCompiler } from \"./compiler\";\nimport { getSha256 } from \"./source\";\nimport type { CompileMode, FullArtifactName } from \"./package\";\nimport { fullNameToString, typedArtifactNameToString } from \"./package\";\nimport { ArtifactSource, parseSourceFile } from \"./source\";\nimport { newTemplateFromContent, templateToSource } from \"./template\";\nimport type winston from \"winston\";\nimport { tryResolve, tryResolveOrError } from \"@milaboratories/resolve-helper\";\nimport { serializeTemplate } from \"@milaboratories/pl-model-backend\";\n\ninterface PackageId {\n /** Package name from package.json */\n readonly name: string;\n /** Package version from package.json */\n readonly version: string;\n}\n\ninterface PackageInfo extends PackageId {\n /** Package type from package.json */\n readonly type: string | undefined;\n /** Path to package root */\n readonly root: string;\n /** Context of package info */\n readonly context: PackageInfoContext;\n /** Dependencies */\n readonly dependencies: PackageInfo[];\n}\n\ninterface PackageJson {\n name: string;\n version: string;\n type: string | undefined;\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n}\n\nconst compiledTplSuffix = \".plj.gz\";\nconst compiledLibSuffix = \".lib.tengo\";\nconst compiledSoftwareSuffix = \".sw.json\";\nconst compiledAssetSuffix = \".as.json\";\n\n// We need to keep track of dependencies for correct tgo-test CLI utility configuraiton.\n// It is much simpler to do this here, than duplicate all tle logic regarding dependencies\n// in go code.\nconst srcTestSuffix = \".test.tengo\";\n\nconst srcTplSuffix = \".tpl.tengo\";\nconst srcLibSuffix = \".lib.tengo\";\nconst srcSoftwareSuffix = \".sw.json\";\nconst srcAssetSuffix = \".as.json\";\nconst compilableSuffixes = [srcLibSuffix, srcTplSuffix, srcSoftwareSuffix, srcAssetSuffix];\n\n/**\n * Resolves path to package.json file of the given dependency package.\n */\nfunction resolvePackageJsonPackage(root: string, depPackageName: string): string | undefined {\n if (!path.isAbsolute(root)) {\n throw new Error(`Root path must be absolute: ${root}`);\n }\n\n // First approach: resolving package's main entry point and try to find package.json\n // in dir tree upwards.\n let resolved = tryResolve(root, depPackageName);\n if (resolved) {\n let depth = 0;\n do {\n const p = path.join(resolved, \"package.json\");\n if (pathType(p) === \"file\") return p;\n depth++;\n resolved = path.dirname(resolved);\n } while (depth < 7 && path.basename(resolved) !== \"node_modules\");\n }\n\n // Second approach: trying to find package.json in the package dir.\n const resolved2 = tryResolveOrError(root, `${depPackageName}/package.json`);\n if (resolved2.result === undefined) {\n if (resolved2.err === \"ERR_PACKAGE_PATH_NOT_EXPORTED\")\n // tolerating not-exported package.json for dev dependencies\n return undefined;\n throw new Error(\n `Can't resolve package.json for package ${depPackageName ?? \".\"} relative to ${root}`,\n );\n }\n return resolved2.result;\n}\n\nexport function resolvePackageJsonRoot(root: string): string {\n if (!path.isAbsolute(root)) {\n throw new Error(`Root path must be absolute: ${root}`);\n }\n\n const p = path.join(root, \"package.json\");\n if (pathType(p) === \"file\") return p;\n throw new Error(`Can't resolve package.json in ${root}`);\n}\n\ntype PackageInfoContext = \"root\" | \"dependency\" | \"devDependency\";\n\n/**\n * Get package info from package.json and all dependencies.\n */\nexport function getPackageInfo(\n root: string,\n logger: winston.Logger,\n context: PackageInfoContext = \"root\",\n): PackageInfo {\n const packageJsonPath = resolvePackageJsonRoot(root);\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString()) as PackageJson;\n\n // resolving dependencies\n const depInfos: PackageInfo[] = [];\n\n if (packageJson.dependencies && context !== \"devDependency\") {\n for (const dep of Object.keys(packageJson.dependencies)) {\n const depPackageJson = resolvePackageJsonPackage(root, dep);\n if (depPackageJson === undefined)\n throw new Error(`Can't resolve package.json for dependency ${dep} of ${root}`);\n const depRoot = path.dirname(depPackageJson);\n depInfos.push(getPackageInfo(depRoot, logger, \"dependency\"));\n }\n }\n\n if (packageJson.devDependencies && context === \"root\") {\n for (const dep of Object.keys(packageJson.devDependencies)) {\n const depPackageJson = resolvePackageJsonPackage(root, dep);\n if (depPackageJson === undefined) {\n logger.warn(`Can't resolve package.json for dev dependency ${dep} of ${root}`);\n // tolerating not-exported package.json for dev dependencies\n continue;\n }\n const depRoot = path.dirname(depPackageJson);\n depInfos.push(getPackageInfo(depRoot, logger, \"devDependency\"));\n }\n }\n\n return {\n name: packageJson.name,\n version: packageJson.version,\n type: packageJson.type,\n dependencies: depInfos,\n root,\n context,\n };\n}\n\nfunction resolveLibsDst(mode: CompileMode, root: string) {\n return path.resolve(root, mode, \"tengo\", \"lib\");\n}\n\nfunction resolveTemplatesDst(mode: CompileMode, root: string) {\n return path.resolve(root, mode, \"tengo\", \"tpl\");\n}\n\nfunction resolveSoftwareDst(mode: CompileMode, root: string) {\n return path.resolve(root, mode, \"tengo\", \"software\");\n}\n\nfunction resolveAssetsDst(mode: CompileMode, root: string) {\n return path.resolve(root, mode, \"tengo\", \"asset\");\n}\n\nfunction loadDependencies(\n logger: winston.Logger,\n compiler: TengoTemplateCompiler,\n packageInfo: PackageInfo,\n): void {\n for (const dep of packageInfo.dependencies) loadDependencies(logger, compiler, dep);\n\n if (packageInfo.context === \"root\")\n // we are not reading compiled files for root package\n return;\n\n // we are in package folder\n const libDistFolder = resolveLibsDst(\"dist\", packageInfo.root);\n const tplDistFolder = resolveTemplatesDst(\"dist\", packageInfo.root);\n const softwareDistFolder = resolveSoftwareDst(\"dist\", packageInfo.root);\n const assetDistFolder = resolveAssetsDst(\"dist\", packageInfo.root);\n\n const libDistExists = pathType(libDistFolder) === \"dir\";\n const tplDistExists = pathType(tplDistFolder) === \"dir\";\n const softwareDistExists = pathType(softwareDistFolder) === \"dir\";\n const assetDistExists = pathType(assetDistFolder) === \"dir\";\n\n if (!libDistExists && !tplDistExists && !softwareDistExists && !assetDistExists)\n // if neither of tengo-specific folders detected, skipping package\n return;\n\n const packageId = { name: packageInfo.name, version: packageInfo.version };\n\n if (libDistExists) {\n loadLibsFromDir(logger, packageId, \"dist\", libDistFolder, compiler);\n }\n\n if (tplDistExists) {\n loadTemplatesFromDir(logger, packageId, \"dist\", tplDistFolder, compiler);\n }\n\n if (softwareDistExists) {\n loadSoftwareFromDir(logger, packageId, \"dist\", softwareDistFolder, compiler);\n }\n\n if (assetDistExists) {\n loadAssetsFromDir(logger, packageId, \"dist\", assetDistFolder, compiler);\n }\n}\n\nfunction loadLibsFromDir(\n logger: winston.Logger,\n packageId: PackageId,\n mode: CompileMode,\n folder: string,\n compiler: TengoTemplateCompiler,\n) {\n for (const f of fs.readdirSync(folder)) {\n const file = path.resolve(folder, f);\n if (!f.endsWith(compiledLibSuffix)) throw new Error(`unexpected file in 'lib' folder: ${file}`);\n const fullName: FullArtifactName = {\n type: \"library\",\n pkg: packageId.name,\n id: f.slice(0, f.length - compiledLibSuffix.length),\n version: packageId.version,\n };\n const src = parseSourceFile(logger, mode, file, fullName, true);\n compiler.addLib(src);\n logger.debug(`Adding dependency ${fullNameToString(fullName)} from ${file}`);\n if (src.dependencies.length > 0) {\n logger.debug(\"Dependencies:\");\n for (const dep of src.dependencies) logger.debug(` - ${typedArtifactNameToString(dep)}`);\n }\n }\n}\n\nfunction loadTemplatesFromDir(\n logger: winston.Logger,\n packageId: PackageId,\n mode: CompileMode,\n folder: string,\n compiler: TengoTemplateCompiler,\n) {\n // adding templates\n for (const f of fs.readdirSync(folder)) {\n const file = path.resolve(folder, f);\n if (!f.endsWith(compiledTplSuffix)) throw new Error(`unexpected file in 'tpl' folder: ${file}`);\n const fullName: FullArtifactName = {\n type: \"template\",\n pkg: packageId.name,\n id: f.slice(0, f.length - compiledTplSuffix.length),\n version: packageId.version,\n };\n const tpl = newTemplateFromContent(mode, fullName, fs.readFileSync(file));\n compiler.addTemplate(templateToSource(tpl));\n logger.debug(`Adding dependency ${fullNameToString(fullName)} from ${file}`);\n }\n}\n\nfunction loadSoftwareFromDir(\n logger: winston.Logger,\n packageId: PackageId,\n mode: CompileMode,\n folder: string,\n compiler: TengoTemplateCompiler,\n) {\n for (const f of fs.readdirSync(folder)) {\n const file = path.resolve(folder, f);\n if (!f.endsWith(compiledSoftwareSuffix))\n throw new Error(`unexpected file in 'software' folder: ${file}`);\n const fullName: FullArtifactName = {\n type: \"software\",\n pkg: packageId.name,\n id: f.slice(0, f.length - compiledSoftwareSuffix.length),\n version: packageId.version,\n };\n\n const source = fs.readFileSync(file).toString();\n\n const software = new ArtifactSource(mode, fullName, getSha256(source), source, file, [], []);\n\n logger.debug(`Adding dependency ${fullNameToString(fullName)} from ${file}`);\n compiler.addSoftware(software);\n }\n}\n\nfunction loadAssetsFromDir(\n logger: winston.Logger,\n packageId: PackageId,\n mode: CompileMode,\n folder: string,\n compiler: TengoTemplateCompiler,\n) {\n for (const f of fs.readdirSync(folder)) {\n const file = path.resolve(folder, f);\n if (!f.endsWith(compiledAssetSuffix))\n throw new Error(`unexpected file in 'asset' folder: ${file}`);\n const fullName: FullArtifactName = {\n type: \"asset\",\n pkg: packageId.name,\n id: f.slice(0, f.length - compiledAssetSuffix.length),\n version: packageId.version,\n };\n\n const source = fs.readFileSync(file).toString();\n\n const asset = new ArtifactSource(mode, fullName, getSha256(source), source, file, [], []);\n\n logger.debug(`Adding dependency ${fullNameToString(fullName)} from ${file}`);\n compiler.addAsset(asset);\n }\n}\n\nexport function parseSources(\n logger: winston.Logger,\n packageId: PackageId,\n mode: CompileMode,\n root: string,\n subdir: string,\n): ArtifactSource[] {\n const sources: ArtifactSource[] = [];\n\n for (const f of fs.readdirSync(path.join(root, subdir))) {\n const inRootPath = path.join(subdir, f); // path to item inside given <root>\n const fullPath = path.join(root, inRootPath); // full path to item from CWD (or abs path, if <root> is abs path)\n\n if (pathType(fullPath) === \"dir\") {\n const nested = parseSources(logger, packageId, mode, root, inRootPath);\n sources.push(...nested);\n continue;\n }\n\n // Handling index.lib.tengo files: rename them to <package-name>.lib.tengo\n const artifactName =\n f === \"index.lib.tengo\" ? `${path.dirname(inRootPath)}.lib.tengo` : inRootPath;\n\n const fullName = fullNameFromFileName(packageId, artifactName.replaceAll(path.sep, \".\"));\n if (!fullName) {\n logger.info(`Skipping unknown file type: ${artifactName}`);\n continue; // skip unknown file types\n }\n\n // if (subdir != '') {\n // throw new Error(`Templates and libraries should reside only inside '${root}' dir.\n // You are free to have any file and dirs structure inside '${root}' keeping other files where you want,\n // but regarding ${compilableSuffixes.join(', ')}, the flat file structure is mandatory.`);\n // }\n\n const file = path.resolve(root, inRootPath);\n logger.debug(`Parsing ${fullNameToString(fullName)} from ${file}`);\n const newSrc = parseSourceFile(logger, mode, file, fullName, true);\n if (newSrc.dependencies.length > 0) {\n logger.debug(\"Detected dependencies:\");\n for (const dep of newSrc.dependencies) logger.debug(` - ${typedArtifactNameToString(dep)}`);\n }\n\n sources.push(newSrc);\n }\n\n return sources;\n}\n\nexport function newCompiler(\n logger: winston.Logger,\n packageInfo: PackageInfo,\n mode: CompileMode,\n): TengoTemplateCompiler {\n const compiler = new TengoTemplateCompiler(mode);\n\n // collect all data (templates, libs and software) from dependency tree\n loadDependencies(logger, compiler, packageInfo);\n\n return compiler;\n}\n\nexport function fullNameFromFileName(\n packageId: PackageId,\n artifactName: string,\n): FullArtifactName | null {\n const pkgAndVersion = { pkg: packageId.name, version: packageId.version };\n if (artifactName.endsWith(srcLibSuffix)) {\n return {\n ...pkgAndVersion,\n id: artifactName.substring(0, artifactName.length - srcLibSuffix.length),\n type: \"library\",\n };\n }\n\n if (artifactName.endsWith(srcTplSuffix)) {\n return {\n ...pkgAndVersion,\n id: artifactName.substring(0, artifactName.length - srcTplSuffix.length),\n type: \"template\",\n };\n }\n\n if (artifactName.endsWith(srcSoftwareSuffix)) {\n return {\n ...pkgAndVersion,\n id: artifactName.substring(0, artifactName.length - srcSoftwareSuffix.length),\n type: \"software\",\n };\n }\n\n if (artifactName.endsWith(srcAssetSuffix)) {\n return {\n ...pkgAndVersion,\n id: artifactName.substring(0, artifactName.length - srcAssetSuffix.length),\n type: \"asset\",\n };\n }\n\n if (artifactName.endsWith(srcTestSuffix)) {\n return {\n ...pkgAndVersion,\n id: artifactName.substring(0, artifactName.length - srcTestSuffix.length),\n type: \"test\",\n };\n }\n\n return null;\n}\n\nexport function compile(\n logger: winston.Logger,\n packageInfo: PackageInfo,\n mode: CompileMode,\n): TemplatesAndLibs {\n const compiler = newCompiler(logger, packageInfo, mode);\n const sources = parseSources(logger, packageInfo, mode, \"src\", \"\");\n\n // checking that we have something to do\n if (sources.length === 0) {\n const lookFor: string[] = [];\n for (const suffix of compilableSuffixes) {\n lookFor.push(`*${suffix}`);\n }\n\n logger.error(`Nothing to compile. Looked for ${lookFor.join(\", \")}`);\n process.exit(1);\n }\n\n // compilation\n logger.info(`Compiling '${mode}'...`);\n const compiled = compiler.compileAndAdd(sources);\n logger.debug(`Done.`);\n\n return compiled;\n}\n\nexport function savePacks(logger: winston.Logger, compiled: TemplatesAndLibs, mode: CompileMode) {\n // writing libs\n if (compiled.libs.length > 0) {\n const libOutput = resolveLibsDst(mode, \".\");\n fs.mkdirSync(libOutput, { recursive: true });\n for (const lib of compiled.libs) {\n const file = path.resolve(libOutput, lib.fullName.id + compiledLibSuffix);\n logger.info(` - writing ${file}`);\n fs.writeFileSync(file, lib.src);\n }\n }\n\n // writing templates\n if (compiled.templates.length > 0) {\n const tplOutput = resolveTemplatesDst(mode, \".\");\n fs.mkdirSync(tplOutput, { recursive: true });\n for (const tpl of compiled.templates) {\n const file = path.resolve(tplOutput, tpl.fullName.id + compiledTplSuffix);\n logger.info(` - writing ${file}`);\n fs.writeFileSync(file, serializeTemplate(tpl.data));\n }\n }\n\n // writing software\n if (compiled.software.length > 0) {\n const swOutput = resolveSoftwareDst(mode, \".\");\n fs.mkdirSync(swOutput, { recursive: true });\n for (const sw of compiled.software) {\n const file = path.resolve(swOutput, sw.fullName.id + compiledSoftwareSuffix);\n logger.info(` - writing ${file}`);\n fs.writeFileSync(file, sw.src);\n }\n }\n\n // writing assets\n if (compiled.assets.length > 0) {\n const swOutput = resolveAssetsDst(mode, \".\");\n fs.mkdirSync(swOutput, { recursive: true });\n for (const sw of compiled.software) {\n const file = path.resolve(swOutput, sw.fullName.id + compiledAssetSuffix);\n logger.info(` - writing ${file}`);\n fs.writeFileSync(file, sw.src);\n }\n }\n}\n"],"mappings":";;;;;;;;;;AA0CA,MAAM,oBAAoB;AAC1B,MAAM,oBAAoB;AAC1B,MAAM,yBAAyB;AAC/B,MAAM,sBAAsB;AAK5B,MAAM,gBAAgB;AAEtB,MAAM,eAAe;AACrB,MAAM,eAAe;AACrB,MAAM,oBAAoB;AAC1B,MAAM,iBAAiB;AACvB,MAAM,qBAAqB;CAAC;CAAc;CAAc;CAAmB;CAAe;;;;AAK1F,SAAS,0BAA0B,MAAc,gBAA4C;AAC3F,KAAI,CAAC,KAAK,WAAW,KAAK,CACxB,OAAM,IAAI,MAAM,+BAA+B,OAAO;CAKxD,IAAI,WAAW,WAAW,MAAM,eAAe;AAC/C,KAAI,UAAU;EACZ,IAAI,QAAQ;AACZ,KAAG;GACD,MAAM,IAAI,KAAK,KAAK,UAAU,eAAe;AAC7C,OAAI,SAAS,EAAE,KAAK,OAAQ,QAAO;AACnC;AACA,cAAW,KAAK,QAAQ,SAAS;WAC1B,QAAQ,KAAK,KAAK,SAAS,SAAS,KAAK;;CAIpD,MAAM,YAAY,kBAAkB,MAAM,GAAG,eAAe,eAAe;AAC3E,KAAI,UAAU,WAAW,KAAA,GAAW;AAClC,MAAI,UAAU,QAAQ,gCAEpB,QAAO,KAAA;AACT,QAAM,IAAI,MACR,0CAA0C,kBAAkB,IAAI,eAAe,OAChF;;AAEH,QAAO,UAAU;;AAGnB,SAAgB,uBAAuB,MAAsB;AAC3D,KAAI,CAAC,KAAK,WAAW,KAAK,CACxB,OAAM,IAAI,MAAM,+BAA+B,OAAO;CAGxD,MAAM,IAAI,KAAK,KAAK,MAAM,eAAe;AACzC,KAAI,SAAS,EAAE,KAAK,OAAQ,QAAO;AACnC,OAAM,IAAI,MAAM,iCAAiC,OAAO;;;;;AAQ1D,SAAgB,eACd,MACA,QACA,UAA8B,QACjB;CACb,MAAM,kBAAkB,uBAAuB,KAAK;CACpD,MAAM,cAAc,KAAK,MAAM,GAAG,aAAa,gBAAgB,CAAC,UAAU,CAAC;CAG3E,MAAM,WAA0B,EAAE;AAElC,KAAI,YAAY,gBAAgB,YAAY,gBAC1C,MAAK,MAAM,OAAO,OAAO,KAAK,YAAY,aAAa,EAAE;EACvD,MAAM,iBAAiB,0BAA0B,MAAM,IAAI;AAC3D,MAAI,mBAAmB,KAAA,EACrB,OAAM,IAAI,MAAM,6CAA6C,IAAI,MAAM,OAAO;EAChF,MAAM,UAAU,KAAK,QAAQ,eAAe;AAC5C,WAAS,KAAK,eAAe,SAAS,QAAQ,aAAa,CAAC;;AAIhE,KAAI,YAAY,mBAAmB,YAAY,OAC7C,MAAK,MAAM,OAAO,OAAO,KAAK,YAAY,gBAAgB,EAAE;EAC1D,MAAM,iBAAiB,0BAA0B,MAAM,IAAI;AAC3D,MAAI,mBAAmB,KAAA,GAAW;AAChC,UAAO,KAAK,iDAAiD,IAAI,MAAM,OAAO;AAE9E;;EAEF,MAAM,UAAU,KAAK,QAAQ,eAAe;AAC5C,WAAS,KAAK,eAAe,SAAS,QAAQ,gBAAgB,CAAC;;AAInE,QAAO;EACL,MAAM,YAAY;EAClB,SAAS,YAAY;EACrB,MAAM,YAAY;EAClB,cAAc;EACd;EACA;EACD;;AAGH,SAAS,eAAe,MAAmB,MAAc;AACvD,QAAO,KAAK,QAAQ,MAAM,MAAM,SAAS,MAAM;;AAGjD,SAAS,oBAAoB,MAAmB,MAAc;AAC5D,QAAO,KAAK,QAAQ,MAAM,MAAM,SAAS,MAAM;;AAGjD,SAAS,mBAAmB,MAAmB,MAAc;AAC3D,QAAO,KAAK,QAAQ,MAAM,MAAM,SAAS,WAAW;;AAGtD,SAAS,iBAAiB,MAAmB,MAAc;AACzD,QAAO,KAAK,QAAQ,MAAM,MAAM,SAAS,QAAQ;;AAGnD,SAAS,iBACP,QACA,UACA,aACM;AACN,MAAK,MAAM,OAAO,YAAY,aAAc,kBAAiB,QAAQ,UAAU,IAAI;AAEnF,KAAI,YAAY,YAAY,OAE1B;CAGF,MAAM,gBAAgB,eAAe,QAAQ,YAAY,KAAK;CAC9D,MAAM,gBAAgB,oBAAoB,QAAQ,YAAY,KAAK;CACnE,MAAM,qBAAqB,mBAAmB,QAAQ,YAAY,KAAK;CACvE,MAAM,kBAAkB,iBAAiB,QAAQ,YAAY,KAAK;CAElE,MAAM,gBAAgB,SAAS,cAAc,KAAK;CAClD,MAAM,gBAAgB,SAAS,cAAc,KAAK;CAClD,MAAM,qBAAqB,SAAS,mBAAmB,KAAK;CAC5D,MAAM,kBAAkB,SAAS,gBAAgB,KAAK;AAEtD,KAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,gBAE9D;CAEF,MAAM,YAAY;EAAE,MAAM,YAAY;EAAM,SAAS,YAAY;EAAS;AAE1E,KAAI,cACF,iBAAgB,QAAQ,WAAW,QAAQ,eAAe,SAAS;AAGrE,KAAI,cACF,sBAAqB,QAAQ,WAAW,QAAQ,eAAe,SAAS;AAG1E,KAAI,mBACF,qBAAoB,QAAQ,WAAW,QAAQ,oBAAoB,SAAS;AAG9E,KAAI,gBACF,mBAAkB,QAAQ,WAAW,QAAQ,iBAAiB,SAAS;;AAI3E,SAAS,gBACP,QACA,WACA,MACA,QACA,UACA;AACA,MAAK,MAAM,KAAK,GAAG,YAAY,OAAO,EAAE;EACtC,MAAM,OAAO,KAAK,QAAQ,QAAQ,EAAE;AACpC,MAAI,CAAC,EAAE,SAAS,kBAAkB,CAAE,OAAM,IAAI,MAAM,oCAAoC,OAAO;EAC/F,MAAM,WAA6B;GACjC,MAAM;GACN,KAAK,UAAU;GACf,IAAI,EAAE,MAAM,GAAG,EAAE,SAAS,GAAyB;GACnD,SAAS,UAAU;GACpB;EACD,MAAM,MAAM,gBAAgB,QAAQ,MAAM,MAAM,UAAU,KAAK;AAC/D,WAAS,OAAO,IAAI;AACpB,SAAO,MAAM,qBAAqB,iBAAiB,SAAS,CAAC,QAAQ,OAAO;AAC5E,MAAI,IAAI,aAAa,SAAS,GAAG;AAC/B,UAAO,MAAM,gBAAgB;AAC7B,QAAK,MAAM,OAAO,IAAI,aAAc,QAAO,MAAM,OAAO,0BAA0B,IAAI,GAAG;;;;AAK/F,SAAS,qBACP,QACA,WACA,MACA,QACA,UACA;AAEA,MAAK,MAAM,KAAK,GAAG,YAAY,OAAO,EAAE;EACtC,MAAM,OAAO,KAAK,QAAQ,QAAQ,EAAE;AACpC,MAAI,CAAC,EAAE,SAAS,kBAAkB,CAAE,OAAM,IAAI,MAAM,oCAAoC,OAAO;EAC/F,MAAM,WAA6B;GACjC,MAAM;GACN,KAAK,UAAU;GACf,IAAI,EAAE,MAAM,GAAG,EAAE,SAAS,EAAyB;GACnD,SAAS,UAAU;GACpB;EACD,MAAM,MAAM,uBAAuB,MAAM,UAAU,GAAG,aAAa,KAAK,CAAC;AACzE,WAAS,YAAY,iBAAiB,IAAI,CAAC;AAC3C,SAAO,MAAM,qBAAqB,iBAAiB,SAAS,CAAC,QAAQ,OAAO;;;AAIhF,SAAS,oBACP,QACA,WACA,MACA,QACA,UACA;AACA,MAAK,MAAM,KAAK,GAAG,YAAY,OAAO,EAAE;EACtC,MAAM,OAAO,KAAK,QAAQ,QAAQ,EAAE;AACpC,MAAI,CAAC,EAAE,SAAS,uBAAuB,CACrC,OAAM,IAAI,MAAM,yCAAyC,OAAO;EAClE,MAAM,WAA6B;GACjC,MAAM;GACN,KAAK,UAAU;GACf,IAAI,EAAE,MAAM,GAAG,EAAE,SAAS,EAA8B;GACxD,SAAS,UAAU;GACpB;EAED,MAAM,SAAS,GAAG,aAAa,KAAK,CAAC,UAAU;EAE/C,MAAM,WAAW,IAAI,eAAe,MAAM,UAAU,UAAU,OAAO,EAAE,QAAQ,MAAM,EAAE,EAAE,EAAE,CAAC;AAE5F,SAAO,MAAM,qBAAqB,iBAAiB,SAAS,CAAC,QAAQ,OAAO;AAC5E,WAAS,YAAY,SAAS;;;AAIlC,SAAS,kBACP,QACA,WACA,MACA,QACA,UACA;AACA,MAAK,MAAM,KAAK,GAAG,YAAY,OAAO,EAAE;EACtC,MAAM,OAAO,KAAK,QAAQ,QAAQ,EAAE;AACpC,MAAI,CAAC,EAAE,SAAS,oBAAoB,CAClC,OAAM,IAAI,MAAM,sCAAsC,OAAO;EAC/D,MAAM,WAA6B;GACjC,MAAM;GACN,KAAK,UAAU;GACf,IAAI,EAAE,MAAM,GAAG,EAAE,SAAS,EAA2B;GACrD,SAAS,UAAU;GACpB;EAED,MAAM,SAAS,GAAG,aAAa,KAAK,CAAC,UAAU;EAE/C,MAAM,QAAQ,IAAI,eAAe,MAAM,UAAU,UAAU,OAAO,EAAE,QAAQ,MAAM,EAAE,EAAE,EAAE,CAAC;AAEzF,SAAO,MAAM,qBAAqB,iBAAiB,SAAS,CAAC,QAAQ,OAAO;AAC5E,WAAS,SAAS,MAAM;;;AAI5B,SAAgB,aACd,QACA,WACA,MACA,MACA,QACkB;CAClB,MAAM,UAA4B,EAAE;AAEpC,MAAK,MAAM,KAAK,GAAG,YAAY,KAAK,KAAK,MAAM,OAAO,CAAC,EAAE;EACvD,MAAM,aAAa,KAAK,KAAK,QAAQ,EAAE;AAGvC,MAAI,SAFa,KAAK,KAAK,MAAM,WAAW,CAEtB,KAAK,OAAO;GAChC,MAAM,SAAS,aAAa,QAAQ,WAAW,MAAM,MAAM,WAAW;AACtE,WAAQ,KAAK,GAAG,OAAO;AACvB;;EAIF,MAAM,eACJ,MAAM,oBAAoB,GAAG,KAAK,QAAQ,WAAW,CAAC,cAAc;EAEtE,MAAM,WAAW,qBAAqB,WAAW,aAAa,WAAW,KAAK,KAAK,IAAI,CAAC;AACxF,MAAI,CAAC,UAAU;AACb,UAAO,KAAK,+BAA+B,eAAe;AAC1D;;EASF,MAAM,OAAO,KAAK,QAAQ,MAAM,WAAW;AAC3C,SAAO,MAAM,WAAW,iBAAiB,SAAS,CAAC,QAAQ,OAAO;EAClE,MAAM,SAAS,gBAAgB,QAAQ,MAAM,MAAM,UAAU,KAAK;AAClE,MAAI,OAAO,aAAa,SAAS,GAAG;AAClC,UAAO,MAAM,yBAAyB;AACtC,QAAK,MAAM,OAAO,OAAO,aAAc,QAAO,MAAM,OAAO,0BAA0B,IAAI,GAAG;;AAG9F,UAAQ,KAAK,OAAO;;AAGtB,QAAO;;AAGT,SAAgB,YACd,QACA,aACA,MACuB;CACvB,MAAM,WAAW,IAAI,sBAAsB,KAAK;AAGhD,kBAAiB,QAAQ,UAAU,YAAY;AAE/C,QAAO;;AAGT,SAAgB,qBACd,WACA,cACyB;CACzB,MAAM,gBAAgB;EAAE,KAAK,UAAU;EAAM,SAAS,UAAU;EAAS;AACzE,KAAI,aAAa,SAAS,aAAa,CACrC,QAAO;EACL,GAAG;EACH,IAAI,aAAa,UAAU,GAAG,aAAa,SAAS,GAAoB;EACxE,MAAM;EACP;AAGH,KAAI,aAAa,SAAS,aAAa,CACrC,QAAO;EACL,GAAG;EACH,IAAI,aAAa,UAAU,GAAG,aAAa,SAAS,GAAoB;EACxE,MAAM;EACP;AAGH,KAAI,aAAa,SAAS,kBAAkB,CAC1C,QAAO;EACL,GAAG;EACH,IAAI,aAAa,UAAU,GAAG,aAAa,SAAS,EAAyB;EAC7E,MAAM;EACP;AAGH,KAAI,aAAa,SAAS,eAAe,CACvC,QAAO;EACL,GAAG;EACH,IAAI,aAAa,UAAU,GAAG,aAAa,SAAS,EAAsB;EAC1E,MAAM;EACP;AAGH,KAAI,aAAa,SAAS,cAAc,CACtC,QAAO;EACL,GAAG;EACH,IAAI,aAAa,UAAU,GAAG,aAAa,SAAS,GAAqB;EACzE,MAAM;EACP;AAGH,QAAO;;AAGT,SAAgB,QACd,QACA,aACA,MACkB;CAClB,MAAM,WAAW,YAAY,QAAQ,aAAa,KAAK;CACvD,MAAM,UAAU,aAAa,QAAQ,aAAa,MAAM,OAAO,GAAG;AAGlE,KAAI,QAAQ,WAAW,GAAG;EACxB,MAAM,UAAoB,EAAE;AAC5B,OAAK,MAAM,UAAU,mBACnB,SAAQ,KAAK,IAAI,SAAS;AAG5B,SAAO,MAAM,kCAAkC,QAAQ,KAAK,KAAK,GAAG;AACpE,UAAQ,KAAK,EAAE;;AAIjB,QAAO,KAAK,cAAc,KAAK,MAAM;CACrC,MAAM,WAAW,SAAS,cAAc,QAAQ;AAChD,QAAO,MAAM,QAAQ;AAErB,QAAO;;AAGT,SAAgB,UAAU,QAAwB,UAA4B,MAAmB;AAE/F,KAAI,SAAS,KAAK,SAAS,GAAG;EAC5B,MAAM,YAAY,eAAe,MAAM,IAAI;AAC3C,KAAG,UAAU,WAAW,EAAE,WAAW,MAAM,CAAC;AAC5C,OAAK,MAAM,OAAO,SAAS,MAAM;GAC/B,MAAM,OAAO,KAAK,QAAQ,WAAW,IAAI,SAAS,KAAK,kBAAkB;AACzE,UAAO,KAAK,eAAe,OAAO;AAClC,MAAG,cAAc,MAAM,IAAI,IAAI;;;AAKnC,KAAI,SAAS,UAAU,SAAS,GAAG;EACjC,MAAM,YAAY,oBAAoB,MAAM,IAAI;AAChD,KAAG,UAAU,WAAW,EAAE,WAAW,MAAM,CAAC;AAC5C,OAAK,MAAM,OAAO,SAAS,WAAW;GACpC,MAAM,OAAO,KAAK,QAAQ,WAAW,IAAI,SAAS,KAAK,kBAAkB;AACzE,UAAO,KAAK,eAAe,OAAO;AAClC,MAAG,cAAc,MAAM,kBAAkB,IAAI,KAAK,CAAC;;;AAKvD,KAAI,SAAS,SAAS,SAAS,GAAG;EAChC,MAAM,WAAW,mBAAmB,MAAM,IAAI;AAC9C,KAAG,UAAU,UAAU,EAAE,WAAW,MAAM,CAAC;AAC3C,OAAK,MAAM,MAAM,SAAS,UAAU;GAClC,MAAM,OAAO,KAAK,QAAQ,UAAU,GAAG,SAAS,KAAK,uBAAuB;AAC5E,UAAO,KAAK,eAAe,OAAO;AAClC,MAAG,cAAc,MAAM,GAAG,IAAI;;;AAKlC,KAAI,SAAS,OAAO,SAAS,GAAG;EAC9B,MAAM,WAAW,iBAAiB,MAAM,IAAI;AAC5C,KAAG,UAAU,UAAU,EAAE,WAAW,MAAM,CAAC;AAC3C,OAAK,MAAM,MAAM,SAAS,UAAU;GAClC,MAAM,OAAO,KAAK,QAAQ,UAAU,GAAG,SAAS,KAAK,oBAAoB;AACzE,UAAO,KAAK,eAAe,OAAO;AAClC,MAAG,cAAc,MAAM,GAAG,IAAI"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
//#region src/compiler/package.ts
|
|
3
2
|
function artifactKey(name) {
|
|
4
3
|
return `${name.type}||${name.pkg}||${name.id}`;
|
|
@@ -40,7 +39,6 @@ function parseArtefactNameAndVersion(nameAndVersion) {
|
|
|
40
39
|
function fullNameWithoutTypeToString(name) {
|
|
41
40
|
return `${name.pkg}:${name.id}:${name.version}`;
|
|
42
41
|
}
|
|
43
|
-
|
|
44
42
|
//#endregion
|
|
45
43
|
exports.artifactKey = artifactKey;
|
|
46
44
|
exports.artifactNameToString = artifactNameToString;
|
|
@@ -51,4 +49,5 @@ exports.fullNameWithoutTypeToString = fullNameWithoutTypeToString;
|
|
|
51
49
|
exports.parseArtefactNameAndVersion = parseArtefactNameAndVersion;
|
|
52
50
|
exports.typedArtifactNameToString = typedArtifactNameToString;
|
|
53
51
|
exports.typedArtifactNamesEquals = typedArtifactNamesEquals;
|
|
52
|
+
|
|
54
53
|
//# sourceMappingURL=package.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.cjs","names":[],"sources":["../../src/compiler/package.ts"],"sourcesContent":["/*\n Package \"@milaboratory/current-tengo-package\".\n\n Structure:\n\n src/\n local-template.pl.tengo <- this one will be compiled and put into ./dist/tengo/tpl/local-template.pl.pkg\n local-library.tengo <- this one will be normalized and put into ./dist/tengo/lib/local-library.tengo\n main.tpl.tengo <- this one will be compiled into ./dist/tengo/tpl/main.pl.pkg and published by external tool\n\n Code of \"main.tpl.tengo\":\n\n plapi := import(\"plapi\")\n\n plapi.getTemplateId(\"@milaboratory/some-tengo-template\") // -> getTemplateId(\"@milaboratory/some-tengo-template:main\")\n import(\"@milaboratory/some-tengo-library\") // -> import(\"@milaboratory/some-tengo-library:main\")\n\n */\n\nexport type CompileMode = \"dist\";\n\nexport type CompilerOption = {\n /** Option name, like 'hash_override' */\n name: string; // we can't use strict literals typing here as we will break compatibility of the code through the lifetime of the compiler.\n\n /** Arguments of the option. Everything that follows option name */\n args: string[];\n};\n\nexport type ArtifactType = \"library\" | \"template\" | \"test\" | \"software\" | \"asset\";\n\n/** Artifact Name including package version */\nexport interface FullArtifactName {\n /** Dependency type */\n type: ArtifactType;\n\n /** Fully qualified package */\n pkg: string;\n\n /** Id of the artifact inside the package */\n id: string;\n\n /** Package version */\n version: string;\n}\n\nexport type FullArtifactNameWithoutType = Omit<FullArtifactName, \"type\">;\n\nexport type TypedArtifactName = Pick<FullArtifactName, \"type\" | \"pkg\" | \"id\">;\n\nexport type PackageName = Pick<FullArtifactName, \"pkg\" | \"version\">;\n\nexport type ArtifactName = Pick<FullArtifactName, \"pkg\" | \"id\">;\n\nexport function artifactKey(name: TypedArtifactName): string {\n return `${name.type}||${name.pkg}||${name.id}`;\n}\n\nexport function fullNameToString(name: FullArtifactName): string {\n return `${name.type}:${name.pkg}:${name.id}:${name.version}`;\n}\n\n/** used for exceptions */\nexport function typedArtifactNameToString(name: TypedArtifactName): string {\n return `${name.type}:${name.pkg}:${name.id}`;\n}\n\nexport function typedArtifactNamesEquals(\n name1: TypedArtifactName,\n name2: TypedArtifactName,\n): boolean {\n return name1.type == name2.type && name1.pkg == name2.pkg && name1.id == name2.id;\n}\n\nexport function fullNameEquals(name1: FullArtifactName, name2: FullArtifactName): boolean {\n return (\n name1.type == name2.type &&\n name1.pkg == name2.pkg &&\n name1.id == name2.id &&\n name1.version == name2.version\n );\n}\n\n/** used to format artefact name while generating output files */\nexport function artifactNameToString(name: ArtifactName): string {\n return `${name.pkg}:${name.id}`;\n}\n\n/** used to format artefact name and version while generating output files */\nexport function formatArtefactNameAndVersion(name: FullArtifactName): {\n name: string;\n version: string;\n} {\n return { name: artifactNameToString(name), version: name.version };\n}\n\n/** used to format artefact name and version while generating output files */\nexport function parseArtefactNameAndVersion(nameAndVersion: {\n name: string;\n version: string;\n}): FullArtifactNameWithoutType {\n const match = nameAndVersion.name.match(/^(?<pkg>[^:]*):(?<id>[^:]*)$/);\n if (!match) throw new Error(`malformed artifact name: ${nameAndVersion.name}`);\n return { pkg: match.groups![\"pkg\"], id: match.groups![\"id\"], version: nameAndVersion.version };\n}\n\nexport function fullNameWithoutTypeToString(name: FullArtifactNameWithoutType): string {\n return `${name.pkg}:${name.id}:${name.version}`;\n}\n\nexport function fullNameWithoutType(name: FullArtifactName): FullArtifactNameWithoutType {\n return { pkg: name.pkg, id: name.id, version: name.version };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"package.cjs","names":[],"sources":["../../src/compiler/package.ts"],"sourcesContent":["/*\n Package \"@milaboratory/current-tengo-package\".\n\n Structure:\n\n src/\n local-template.pl.tengo <- this one will be compiled and put into ./dist/tengo/tpl/local-template.pl.pkg\n local-library.tengo <- this one will be normalized and put into ./dist/tengo/lib/local-library.tengo\n main.tpl.tengo <- this one will be compiled into ./dist/tengo/tpl/main.pl.pkg and published by external tool\n\n Code of \"main.tpl.tengo\":\n\n plapi := import(\"plapi\")\n\n plapi.getTemplateId(\"@milaboratory/some-tengo-template\") // -> getTemplateId(\"@milaboratory/some-tengo-template:main\")\n import(\"@milaboratory/some-tengo-library\") // -> import(\"@milaboratory/some-tengo-library:main\")\n\n */\n\nexport type CompileMode = \"dist\";\n\nexport type CompilerOption = {\n /** Option name, like 'hash_override' */\n name: string; // we can't use strict literals typing here as we will break compatibility of the code through the lifetime of the compiler.\n\n /** Arguments of the option. Everything that follows option name */\n args: string[];\n};\n\nexport type ArtifactType = \"library\" | \"template\" | \"test\" | \"software\" | \"asset\";\n\n/** Artifact Name including package version */\nexport interface FullArtifactName {\n /** Dependency type */\n type: ArtifactType;\n\n /** Fully qualified package */\n pkg: string;\n\n /** Id of the artifact inside the package */\n id: string;\n\n /** Package version */\n version: string;\n}\n\nexport type FullArtifactNameWithoutType = Omit<FullArtifactName, \"type\">;\n\nexport type TypedArtifactName = Pick<FullArtifactName, \"type\" | \"pkg\" | \"id\">;\n\nexport type PackageName = Pick<FullArtifactName, \"pkg\" | \"version\">;\n\nexport type ArtifactName = Pick<FullArtifactName, \"pkg\" | \"id\">;\n\nexport function artifactKey(name: TypedArtifactName): string {\n return `${name.type}||${name.pkg}||${name.id}`;\n}\n\nexport function fullNameToString(name: FullArtifactName): string {\n return `${name.type}:${name.pkg}:${name.id}:${name.version}`;\n}\n\n/** used for exceptions */\nexport function typedArtifactNameToString(name: TypedArtifactName): string {\n return `${name.type}:${name.pkg}:${name.id}`;\n}\n\nexport function typedArtifactNamesEquals(\n name1: TypedArtifactName,\n name2: TypedArtifactName,\n): boolean {\n return name1.type == name2.type && name1.pkg == name2.pkg && name1.id == name2.id;\n}\n\nexport function fullNameEquals(name1: FullArtifactName, name2: FullArtifactName): boolean {\n return (\n name1.type == name2.type &&\n name1.pkg == name2.pkg &&\n name1.id == name2.id &&\n name1.version == name2.version\n );\n}\n\n/** used to format artefact name while generating output files */\nexport function artifactNameToString(name: ArtifactName): string {\n return `${name.pkg}:${name.id}`;\n}\n\n/** used to format artefact name and version while generating output files */\nexport function formatArtefactNameAndVersion(name: FullArtifactName): {\n name: string;\n version: string;\n} {\n return { name: artifactNameToString(name), version: name.version };\n}\n\n/** used to format artefact name and version while generating output files */\nexport function parseArtefactNameAndVersion(nameAndVersion: {\n name: string;\n version: string;\n}): FullArtifactNameWithoutType {\n const match = nameAndVersion.name.match(/^(?<pkg>[^:]*):(?<id>[^:]*)$/);\n if (!match) throw new Error(`malformed artifact name: ${nameAndVersion.name}`);\n return { pkg: match.groups![\"pkg\"], id: match.groups![\"id\"], version: nameAndVersion.version };\n}\n\nexport function fullNameWithoutTypeToString(name: FullArtifactNameWithoutType): string {\n return `${name.pkg}:${name.id}:${name.version}`;\n}\n\nexport function fullNameWithoutType(name: FullArtifactName): FullArtifactNameWithoutType {\n return { pkg: name.pkg, id: name.id, version: name.version };\n}\n"],"mappings":";AAsDA,SAAgB,YAAY,MAAiC;AAC3D,QAAO,GAAG,KAAK,KAAK,IAAI,KAAK,IAAI,IAAI,KAAK;;AAG5C,SAAgB,iBAAiB,MAAgC;AAC/D,QAAO,GAAG,KAAK,KAAK,GAAG,KAAK,IAAI,GAAG,KAAK,GAAG,GAAG,KAAK;;;AAIrD,SAAgB,0BAA0B,MAAiC;AACzE,QAAO,GAAG,KAAK,KAAK,GAAG,KAAK,IAAI,GAAG,KAAK;;AAG1C,SAAgB,yBACd,OACA,OACS;AACT,QAAO,MAAM,QAAQ,MAAM,QAAQ,MAAM,OAAO,MAAM,OAAO,MAAM,MAAM,MAAM;;AAGjF,SAAgB,eAAe,OAAyB,OAAkC;AACxF,QACE,MAAM,QAAQ,MAAM,QACpB,MAAM,OAAO,MAAM,OACnB,MAAM,MAAM,MAAM,MAClB,MAAM,WAAW,MAAM;;;AAK3B,SAAgB,qBAAqB,MAA4B;AAC/D,QAAO,GAAG,KAAK,IAAI,GAAG,KAAK;;;AAI7B,SAAgB,6BAA6B,MAG3C;AACA,QAAO;EAAE,MAAM,qBAAqB,KAAK;EAAE,SAAS,KAAK;EAAS;;;AAIpE,SAAgB,4BAA4B,gBAGZ;CAC9B,MAAM,QAAQ,eAAe,KAAK,MAAM,+BAA+B;AACvE,KAAI,CAAC,MAAO,OAAM,IAAI,MAAM,4BAA4B,eAAe,OAAO;AAC9E,QAAO;EAAE,KAAK,MAAM,OAAQ;EAAQ,IAAI,MAAM,OAAQ;EAAO,SAAS,eAAe;EAAS;;AAGhG,SAAgB,4BAA4B,MAA2C;AACrF,QAAO,GAAG,KAAK,IAAI,GAAG,KAAK,GAAG,GAAG,KAAK"}
|
package/dist/compiler/package.js
CHANGED
|
@@ -39,7 +39,7 @@ function parseArtefactNameAndVersion(nameAndVersion) {
|
|
|
39
39
|
function fullNameWithoutTypeToString(name) {
|
|
40
40
|
return `${name.pkg}:${name.id}:${name.version}`;
|
|
41
41
|
}
|
|
42
|
-
|
|
43
42
|
//#endregion
|
|
44
43
|
export { artifactKey, artifactNameToString, formatArtefactNameAndVersion, fullNameEquals, fullNameToString, fullNameWithoutTypeToString, parseArtefactNameAndVersion, typedArtifactNameToString, typedArtifactNamesEquals };
|
|
44
|
+
|
|
45
45
|
//# sourceMappingURL=package.js.map
|
package/dist/compiler/source.cjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
const require_package = require(
|
|
3
|
-
const require_artifactset = require(
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_package = require("./package.cjs");
|
|
3
|
+
const require_artifactset = require("./artifactset.cjs");
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
6
|
-
|
|
7
6
|
//#region src/compiler/source.ts
|
|
8
7
|
const namePattern = "[_a-zA-Z][_a-zA-Z0-9]*";
|
|
9
8
|
const functionCallRE = (moduleName, fnName) => {
|
|
@@ -277,9 +276,9 @@ function parseArtifactName(moduleName, aType, localPackageName) {
|
|
|
277
276
|
function getSha256(source) {
|
|
278
277
|
return (0, node_crypto.createHash)("sha256").update(source).digest("hex");
|
|
279
278
|
}
|
|
280
|
-
|
|
281
279
|
//#endregion
|
|
282
280
|
exports.ArtifactSource = ArtifactSource;
|
|
283
281
|
exports.getSha256 = getSha256;
|
|
284
282
|
exports.parseSourceFile = parseSourceFile;
|
|
283
|
+
|
|
285
284
|
//# sourceMappingURL=source.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source.cjs","names":["createArtifactNameSet","fullNameToString"],"sources":["../../src/compiler/source.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport {\n type TypedArtifactName,\n type FullArtifactName,\n type ArtifactType,\n type CompileMode,\n type CompilerOption,\n fullNameToString,\n} from \"./package\";\nimport type { ArtifactMap } from \"./artifactset\";\nimport { createArtifactNameSet } from \"./artifactset\";\nimport { createHash } from \"node:crypto\";\nimport type { MiLogger } from \"@milaboratories/ts-helpers\";\n\n// matches any valid name in tengo. Don't forget to use '\\b' when needed to limit the boundaries!\nconst namePattern = \"[_a-zA-Z][_a-zA-Z0-9]*\";\n\nconst functionCallRE = (moduleName: string, fnName: string) => {\n return new RegExp(\n `\\\\b${moduleName}\\\\.(?<fnCall>(?<fnName>` +\n fnName +\n `)\\\\s*\\\\(\\\\s*\"(?<templateName>[^\"]+)\"\\\\s*\\\\))`,\n \"g\",\n );\n};\n\nconst functionCallLikeRE = (moduleName: string, fnName: string) => {\n return new RegExp(`\\\\b${moduleName}\\\\.(?<fnName>` + fnName + `)\\\\s*\\\\(`, \"g\");\n};\n\nexport const newGetTemplateIdRE = (moduleName: string) =>\n functionCallRE(moduleName, \"getTemplateId\");\nexport const newGetSoftwareInfoRE = (moduleName: string) =>\n functionCallRE(moduleName, \"getSoftwareInfo\");\n\nconst newImportTemplateRE = (moduleName: string) => functionCallRE(moduleName, \"importTemplate\");\nconst newImportTemplateDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importTemplate\");\nconst newImportSoftwareRE = (moduleName: string) => functionCallRE(moduleName, \"importSoftware\");\nconst newImportSoftwareDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importSoftware\");\nconst newImportAssetRE = (moduleName: string) => functionCallRE(moduleName, \"importAsset\");\nconst newImportAssetDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importAsset\");\n\nconst emptyLineRE = /^\\s*$/;\nconst compilerOptionRE = /^\\/\\/tengo:[\\w]/;\nconst wrongCompilerOptionRE = /^\\s*\\/\\/\\s*tengo:\\s*./;\nconst singlelineCommentRE = /^\\s*(\\/\\/)/;\nconst singlelineTerminatedCommentRE = /^\\s*\\/\\*.*\\*\\/\\s*$/; // matches '^/* ... */$' comment lines as a special case of singleline comments.\nconst multilineCommentStartRE = /^\\s*\\/\\*/;\nconst multilineCommentEndRE = /\\*\\//;\nconst multilineStatementRE = /[.,]\\s*$/; // it is hard to consistently treat (\\n\"a\"\\n) multiline statements, we forbid them for now.\n\n// import could only be an assignment in a statement,\n// other ways could break a compilation.\nconst importRE = /\\s*:=\\s*import\\s*\\(\\s*\"(?<moduleName>[^\"]+)\"\\s*\\)/;\nconst importNameRE = new RegExp(\n `\\\\b(?<importName>${namePattern}(\\\\.${namePattern})*)${importRE.source}`,\n);\nconst dependencyRE = /(?<pkgName>[^\"]+)?:(?<depID>[^\"]+)/; // use it to parse <moduleName> from importPattern or <templateName> from getTemplateID\n\n/**\n * Parse compiler option string representation\n * Compiler option line is a comment starting with '//tengo:', say\n * //tengo:hash_override tralala\n *\n * The common compiler option syntax is:\n * //tengo:<option name> [<option arg1> [<option arg 2> [...]]]\n */\nconst parseComplierOption = (opt: string): CompilerOption => {\n const parts = opt.split(\" \");\n const namePart = parts[0].split(\":\");\n if (namePart.length != 2) {\n throw new Error(\n \"compiler option format is wrong: expect to have option name after 'tengo:' prefix, like 'tengo:MyOption'\",\n );\n }\n const optName = namePart[1];\n\n return {\n name: optName,\n args: parts.slice(1),\n };\n};\n\nexport class ArtifactSource {\n constructor(\n /** The mode this artifact was built (dev or dist) */\n public readonly compileMode: CompileMode,\n /** Full artifact id, including package version */\n public readonly fullName: FullArtifactName,\n /** Hash of the source code */\n public readonly sourceHash: string,\n /** Normalized source code */\n public readonly src: string,\n /** Path to source file where artifact came from */\n public readonly srcName: string,\n /** List of dependencies */\n public readonly dependencies: TypedArtifactName[],\n /** Additional compiler options detected in source code */\n public readonly compilerOptions: CompilerOption[],\n ) {}\n}\n\nexport function parseSourceFile(\n logger: MiLogger,\n mode: CompileMode,\n srcFile: string,\n fullSourceName: FullArtifactName,\n normalize: boolean,\n): ArtifactSource {\n const src = readFileSync(srcFile).toString();\n const { deps, normalized, opts } = parseSourceData(logger, src, fullSourceName, normalize);\n\n return new ArtifactSource(\n mode,\n fullSourceName,\n getSha256(normalized),\n normalized,\n srcFile,\n deps.array,\n opts,\n );\n}\n\nexport function parseSource(\n logger: MiLogger,\n mode: CompileMode,\n src: string,\n fullSourceName: FullArtifactName,\n normalize: boolean,\n): ArtifactSource {\n const { deps, normalized, opts } = parseSourceData(logger, src, fullSourceName, normalize);\n\n return new ArtifactSource(\n mode,\n fullSourceName,\n getSha256(normalized),\n normalized,\n \"\",\n deps.array,\n opts,\n );\n}\n\n/**\n * Reads src\n * returns normalized source code,\n * gets dependencies from imports,\n * maps imports to global names if globalizeImports is true,\n * and collects compiler options like hashOverride.\n */\nfunction parseSourceData(\n logger: MiLogger,\n src: string,\n fullSourceName: FullArtifactName,\n globalizeImports: boolean,\n): {\n normalized: string;\n deps: ArtifactMap<TypedArtifactName>;\n opts: CompilerOption[];\n} {\n const dependencySet = createArtifactNameSet();\n const optionList: CompilerOption[] = [];\n\n // iterating over lines\n const lines = src.split(\"\\n\");\n\n // processedLines keep all the original lines from <src>.\n // If <globalizeImport>==true, the parser modifies 'import' and 'getTemplateId' lines\n // with Platforma Tengo lib and template usages, resolving local names (\":<item>\") to\n // global (\"@milaboratory/pkg:<item>\")\n const processedLines: string[] = [];\n let parserContext: sourceParserContext = {\n isInCommentBlock: false,\n canDetectOptions: true,\n artifactImportREs: new Map<string, [ArtifactType, RegExp][]>(),\n importLikeREs: new Map<string, [ArtifactType, RegExp][]>(),\n multilineStatement: \"\",\n lineNo: 0,\n };\n\n for (const line of lines) {\n parserContext.lineNo++;\n\n try {\n const {\n line: processedLine,\n context: newContext,\n artifacts,\n option,\n } = parseSingleSourceLine(logger, line, parserContext, fullSourceName.pkg, globalizeImports);\n processedLines.push(processedLine);\n parserContext = newContext;\n\n for (const artifact of artifacts ?? []) {\n dependencySet.add(artifact);\n }\n if (option) {\n optionList.push(option);\n }\n } catch (error: unknown) {\n const err = error as Error;\n throw new Error(\n `[line ${parserContext.lineNo} in ${fullNameToString(fullSourceName)}]: ${err.message}\\n\\t${line}`,\n { cause: err },\n );\n }\n }\n\n return {\n normalized: processedLines.join(\"\\n\"),\n deps: dependencySet,\n opts: optionList,\n };\n}\n\nexport type sourceParserContext = {\n isInCommentBlock: boolean;\n canDetectOptions: boolean;\n artifactImportREs: Map<string, [ArtifactType, RegExp][]>;\n importLikeREs: Map<string, [ArtifactType, RegExp][]>;\n multilineStatement: string;\n lineNo: number;\n};\n\nexport type lineProcessingResult = {\n line: string;\n context: sourceParserContext;\n artifacts: TypedArtifactName[];\n option: CompilerOption | undefined;\n};\n\nexport function parseSingleSourceLine(\n logger: MiLogger,\n line: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n if (context.isInCommentBlock) {\n if (multilineCommentEndRE.exec(line)) {\n context.isInCommentBlock = false;\n }\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n if (compilerOptionRE.exec(line)) {\n if (!context.canDetectOptions) {\n logger.error(\n `[line ${context.lineNo}]: compiler option '//tengo:' was detected, but it cannot be applied as compiler options can be set only at the file header, before any code line'`,\n );\n throw new Error(\n \"tengo compiler options ('//tengo:' comments) can be set only in file header\",\n );\n }\n return { line, context, artifacts: [], option: parseComplierOption(line) };\n }\n\n if (wrongCompilerOptionRE.exec(line) && context.canDetectOptions) {\n logger.warn(\n `[line ${context.lineNo}]: text simillar to compiler option ('//tengo:...') was detected, but it has wrong format. Leave it as is, if you did not mean to use a line as compiler option. Or format it to '//tengo:<option>' otherwise (no spaces between '//' and 'tengo', no spaces between ':' and option name)`,\n );\n return { line, context, artifacts: [], option: undefined };\n }\n\n if (singlelineCommentRE.test(line) || singlelineTerminatedCommentRE.test(line)) {\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n const canBeInlinedComment = line.includes(\"*/\");\n if (multilineCommentStartRE.exec(line) && !canBeInlinedComment) {\n context.isInCommentBlock = true;\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n const statement = context.multilineStatement + line.trim();\n\n const mayContainAComment = line.includes(\"//\") || line.includes(\"/*\");\n if (multilineStatementRE.test(line) && !mayContainAComment) {\n // We accumulate multiline statements into single line before analyzing them.\n // This dramatically simplifies parsing logic: things like\n //\n // assets.\n // importSoftware(\"a:b\");\n //\n // become simple 'assets.importSoftware(\"a:b\");' for parser checks.\n //\n // For safety reasons, we never consider anything that 'may look like a comment'\n // as a part of multiline statement to prevent joining things like\n //\n // someFnCall() // looks like multiline statement because of dot in the end of a comment.\n //\n // This problem also appears in multiline string literals, but I hope this will not\n // cause problems in real life.\n\n // We still try to process each line to globalize imports in case of complex constructions, when\n // statements are stacked one into another:\n // a.\n // use(assets.importSoftware(\":soft1\")).\n // use(assets.importSoftware(\":soft2\")).\n // run()\n // It is multiline, and it still requires import globalization mid-way, not just for the last line of statement\n const result = processAssetImport(line, statement, context, localPackageName, globalizeImports);\n context.multilineStatement += result.line.trim(); // accumulate the line after imports globalization.\n return result;\n }\n\n context.multilineStatement = \"\"; // reset accumulated multiline statement parts once we reach statement end.\n\n if (emptyLineRE.exec(statement)) {\n return { line, context, artifacts: [], option: undefined };\n }\n\n // options could be only at the top of the file.\n context.canDetectOptions = false;\n\n return processAssetImport(line, statement, context, localPackageName, globalizeImports);\n}\n\nfunction processModuleImport(\n importInstruction: RegExpExecArray,\n originalLine: string,\n statement: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n const iInfo = parseImport(statement);\n\n // If we have plapi, ll or assets, then try to parse\n // getTemplateId, getSoftwareInfo, getSoftware and getAsset calls.\n\n if (iInfo.module === \"plapi\") {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newGetTemplateIdRE(iInfo.alias)],\n [\"software\", newGetSoftwareInfoRE(iInfo.alias)],\n ]);\n }\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n if (\n iInfo.module === \"@milaboratory/tengo-sdk:ll\" ||\n iInfo.module === \"@platforma-sdk/workflow-tengo:ll\" ||\n ((localPackageName === \"@milaboratory/tengo-sdk\" ||\n localPackageName === \"@platforma-sdk/workflow-tengo\") &&\n iInfo.module === \":ll\")\n ) {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newImportTemplateRE(iInfo.alias)],\n [\"software\", newImportSoftwareRE(iInfo.alias)],\n ]);\n }\n }\n\n if (\n iInfo.module === \"@milaboratory/tengo-sdk:assets\" ||\n iInfo.module === \"@platforma-sdk/workflow-tengo:assets\" ||\n ((localPackageName === \"@milaboratory/tengo-sdk\" ||\n localPackageName === \"@platforma-sdk/workflow-tengo\") &&\n iInfo.module === \":assets\")\n ) {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newImportTemplateRE(iInfo.alias)],\n [\"software\", newImportSoftwareRE(iInfo.alias)],\n [\"asset\", newImportAssetRE(iInfo.alias)],\n ]);\n context.importLikeREs.set(iInfo.module, [\n [\"template\", newImportTemplateDetector(iInfo.alias)],\n [\"software\", newImportSoftwareDetector(iInfo.alias)],\n [\"asset\", newImportAssetDetector(iInfo.alias)],\n ]);\n }\n }\n\n const artifact = parseArtifactName(iInfo.module, \"library\", localPackageName);\n if (!artifact) {\n // not a Platforma Tengo library import\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n if (globalizeImports) {\n originalLine = originalLine.replace(\n importInstruction[0],\n ` := import(\"${artifact.pkg}:${artifact.id}\")`,\n );\n }\n\n return { line: originalLine, context, artifacts: [artifact], option: undefined };\n}\n\nfunction processAssetImport(\n originalLine: string,\n statement: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n if (emptyLineRE.exec(statement)) {\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n // options could be only at the top of the file.\n context.canDetectOptions = false;\n\n const importInstruction = importRE.exec(statement);\n\n if (importInstruction) {\n return processModuleImport(\n importInstruction,\n originalLine,\n statement,\n context,\n localPackageName,\n globalizeImports,\n );\n }\n\n if (context.artifactImportREs.size > 0) {\n for (const [_, artifactRE] of context.artifactImportREs) {\n for (const [artifactType, re] of artifactRE) {\n // Find all matches in the statement\n const matches = Array.from(statement.matchAll(re));\n if (matches.length === 0) {\n continue;\n }\n\n const artifacts: TypedArtifactName[] = [];\n for (let i = matches.length - 1; i >= 0; i--) {\n const match = matches[i];\n if (!match || !match.groups) {\n continue;\n }\n\n const { fnCall, templateName, fnName } = match.groups;\n\n if (!fnCall || !templateName || !fnName) {\n throw Error(`failed to parse template import statement`);\n }\n\n const artifact = parseArtifactName(templateName, artifactType, localPackageName);\n if (!artifact) {\n throw Error(`failed to parse artifact name in ${fnName} import statement`);\n }\n artifacts.push(artifact);\n\n if (globalizeImports) {\n // Replace all occurrences of this fnCall in originalLine\n originalLine = originalLine.replaceAll(\n fnCall,\n `${fnName}(\"${artifact.pkg}:${artifact.id}\")`,\n );\n }\n }\n\n return { line: originalLine, context, artifacts, option: undefined };\n }\n }\n }\n\n if (context.importLikeREs.size > 0) {\n for (const [_, artifactRE] of context.importLikeREs) {\n for (const [artifactType, re] of artifactRE) {\n const match = re.exec(statement);\n if (!match || !match.groups) {\n continue;\n }\n\n throw Error(\n `incorrect '${artifactType}' import statement: use string literal as ID (variables are not allowed) in the same line with brackets (i.e. 'importSoftware(\"sw:main\")').`,\n );\n }\n }\n }\n\n return { line: originalLine, context, artifacts: [], option: undefined };\n}\n\ninterface ImportInfo {\n module: string; // the module name without wrapping quotes: import(\"<module>\")\n alias: string; // the name of variable that keeps imported module: <alias> := import(\"<module>\")\n}\n\nfunction parseImport(line: string): ImportInfo {\n const match = importNameRE.exec(line);\n\n if (!match || !match.groups) {\n throw Error(`failed to parse 'import' statement`);\n }\n\n const { importName, moduleName } = match.groups;\n if (!importName || !moduleName) {\n throw Error(`failed to parse 'import' statement`);\n }\n\n return {\n module: moduleName, // the module name without wrapping quotes: import(\"<module>\")\n alias: importName, // the name of variable that keeps imported module: <alias> := import(\"<module>\")\n };\n}\n\nfunction parseArtifactName(\n moduleName: string,\n aType: ArtifactType,\n localPackageName: string,\n): TypedArtifactName | undefined {\n const depInfo = dependencyRE.exec(moduleName);\n if (!depInfo) {\n return;\n }\n\n if (!depInfo.groups) {\n throw Error(\n `failed to parse dependency name inside 'import' statement. The dependency name should have format '<package>:<templateName>'`,\n );\n }\n\n const { pkgName, depID } = depInfo.groups;\n if (!depID) {\n throw Error(\n `failed to parse dependency name inside 'import' statement. The dependency name should have format '<package>:<templateName>'`,\n );\n }\n\n return { type: aType, pkg: pkgName ?? localPackageName, id: depID };\n}\n\nexport function getSha256(source: string): string {\n return createHash(\"sha256\").update(source).digest(\"hex\");\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"source.cjs","names":["createArtifactNameSet","fullNameToString"],"sources":["../../src/compiler/source.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport {\n type TypedArtifactName,\n type FullArtifactName,\n type ArtifactType,\n type CompileMode,\n type CompilerOption,\n fullNameToString,\n} from \"./package\";\nimport type { ArtifactMap } from \"./artifactset\";\nimport { createArtifactNameSet } from \"./artifactset\";\nimport { createHash } from \"node:crypto\";\nimport type { MiLogger } from \"@milaboratories/ts-helpers\";\n\n// matches any valid name in tengo. Don't forget to use '\\b' when needed to limit the boundaries!\nconst namePattern = \"[_a-zA-Z][_a-zA-Z0-9]*\";\n\nconst functionCallRE = (moduleName: string, fnName: string) => {\n return new RegExp(\n `\\\\b${moduleName}\\\\.(?<fnCall>(?<fnName>` +\n fnName +\n `)\\\\s*\\\\(\\\\s*\"(?<templateName>[^\"]+)\"\\\\s*\\\\))`,\n \"g\",\n );\n};\n\nconst functionCallLikeRE = (moduleName: string, fnName: string) => {\n return new RegExp(`\\\\b${moduleName}\\\\.(?<fnName>` + fnName + `)\\\\s*\\\\(`, \"g\");\n};\n\nexport const newGetTemplateIdRE = (moduleName: string) =>\n functionCallRE(moduleName, \"getTemplateId\");\nexport const newGetSoftwareInfoRE = (moduleName: string) =>\n functionCallRE(moduleName, \"getSoftwareInfo\");\n\nconst newImportTemplateRE = (moduleName: string) => functionCallRE(moduleName, \"importTemplate\");\nconst newImportTemplateDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importTemplate\");\nconst newImportSoftwareRE = (moduleName: string) => functionCallRE(moduleName, \"importSoftware\");\nconst newImportSoftwareDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importSoftware\");\nconst newImportAssetRE = (moduleName: string) => functionCallRE(moduleName, \"importAsset\");\nconst newImportAssetDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importAsset\");\n\nconst emptyLineRE = /^\\s*$/;\nconst compilerOptionRE = /^\\/\\/tengo:[\\w]/;\nconst wrongCompilerOptionRE = /^\\s*\\/\\/\\s*tengo:\\s*./;\nconst singlelineCommentRE = /^\\s*(\\/\\/)/;\nconst singlelineTerminatedCommentRE = /^\\s*\\/\\*.*\\*\\/\\s*$/; // matches '^/* ... */$' comment lines as a special case of singleline comments.\nconst multilineCommentStartRE = /^\\s*\\/\\*/;\nconst multilineCommentEndRE = /\\*\\//;\nconst multilineStatementRE = /[.,]\\s*$/; // it is hard to consistently treat (\\n\"a\"\\n) multiline statements, we forbid them for now.\n\n// import could only be an assignment in a statement,\n// other ways could break a compilation.\nconst importRE = /\\s*:=\\s*import\\s*\\(\\s*\"(?<moduleName>[^\"]+)\"\\s*\\)/;\nconst importNameRE = new RegExp(\n `\\\\b(?<importName>${namePattern}(\\\\.${namePattern})*)${importRE.source}`,\n);\nconst dependencyRE = /(?<pkgName>[^\"]+)?:(?<depID>[^\"]+)/; // use it to parse <moduleName> from importPattern or <templateName> from getTemplateID\n\n/**\n * Parse compiler option string representation\n * Compiler option line is a comment starting with '//tengo:', say\n * //tengo:hash_override tralala\n *\n * The common compiler option syntax is:\n * //tengo:<option name> [<option arg1> [<option arg 2> [...]]]\n */\nconst parseComplierOption = (opt: string): CompilerOption => {\n const parts = opt.split(\" \");\n const namePart = parts[0].split(\":\");\n if (namePart.length != 2) {\n throw new Error(\n \"compiler option format is wrong: expect to have option name after 'tengo:' prefix, like 'tengo:MyOption'\",\n );\n }\n const optName = namePart[1];\n\n return {\n name: optName,\n args: parts.slice(1),\n };\n};\n\nexport class ArtifactSource {\n constructor(\n /** The mode this artifact was built (dev or dist) */\n public readonly compileMode: CompileMode,\n /** Full artifact id, including package version */\n public readonly fullName: FullArtifactName,\n /** Hash of the source code */\n public readonly sourceHash: string,\n /** Normalized source code */\n public readonly src: string,\n /** Path to source file where artifact came from */\n public readonly srcName: string,\n /** List of dependencies */\n public readonly dependencies: TypedArtifactName[],\n /** Additional compiler options detected in source code */\n public readonly compilerOptions: CompilerOption[],\n ) {}\n}\n\nexport function parseSourceFile(\n logger: MiLogger,\n mode: CompileMode,\n srcFile: string,\n fullSourceName: FullArtifactName,\n normalize: boolean,\n): ArtifactSource {\n const src = readFileSync(srcFile).toString();\n const { deps, normalized, opts } = parseSourceData(logger, src, fullSourceName, normalize);\n\n return new ArtifactSource(\n mode,\n fullSourceName,\n getSha256(normalized),\n normalized,\n srcFile,\n deps.array,\n opts,\n );\n}\n\nexport function parseSource(\n logger: MiLogger,\n mode: CompileMode,\n src: string,\n fullSourceName: FullArtifactName,\n normalize: boolean,\n): ArtifactSource {\n const { deps, normalized, opts } = parseSourceData(logger, src, fullSourceName, normalize);\n\n return new ArtifactSource(\n mode,\n fullSourceName,\n getSha256(normalized),\n normalized,\n \"\",\n deps.array,\n opts,\n );\n}\n\n/**\n * Reads src\n * returns normalized source code,\n * gets dependencies from imports,\n * maps imports to global names if globalizeImports is true,\n * and collects compiler options like hashOverride.\n */\nfunction parseSourceData(\n logger: MiLogger,\n src: string,\n fullSourceName: FullArtifactName,\n globalizeImports: boolean,\n): {\n normalized: string;\n deps: ArtifactMap<TypedArtifactName>;\n opts: CompilerOption[];\n} {\n const dependencySet = createArtifactNameSet();\n const optionList: CompilerOption[] = [];\n\n // iterating over lines\n const lines = src.split(\"\\n\");\n\n // processedLines keep all the original lines from <src>.\n // If <globalizeImport>==true, the parser modifies 'import' and 'getTemplateId' lines\n // with Platforma Tengo lib and template usages, resolving local names (\":<item>\") to\n // global (\"@milaboratory/pkg:<item>\")\n const processedLines: string[] = [];\n let parserContext: sourceParserContext = {\n isInCommentBlock: false,\n canDetectOptions: true,\n artifactImportREs: new Map<string, [ArtifactType, RegExp][]>(),\n importLikeREs: new Map<string, [ArtifactType, RegExp][]>(),\n multilineStatement: \"\",\n lineNo: 0,\n };\n\n for (const line of lines) {\n parserContext.lineNo++;\n\n try {\n const {\n line: processedLine,\n context: newContext,\n artifacts,\n option,\n } = parseSingleSourceLine(logger, line, parserContext, fullSourceName.pkg, globalizeImports);\n processedLines.push(processedLine);\n parserContext = newContext;\n\n for (const artifact of artifacts ?? []) {\n dependencySet.add(artifact);\n }\n if (option) {\n optionList.push(option);\n }\n } catch (error: unknown) {\n const err = error as Error;\n throw new Error(\n `[line ${parserContext.lineNo} in ${fullNameToString(fullSourceName)}]: ${err.message}\\n\\t${line}`,\n { cause: err },\n );\n }\n }\n\n return {\n normalized: processedLines.join(\"\\n\"),\n deps: dependencySet,\n opts: optionList,\n };\n}\n\nexport type sourceParserContext = {\n isInCommentBlock: boolean;\n canDetectOptions: boolean;\n artifactImportREs: Map<string, [ArtifactType, RegExp][]>;\n importLikeREs: Map<string, [ArtifactType, RegExp][]>;\n multilineStatement: string;\n lineNo: number;\n};\n\nexport type lineProcessingResult = {\n line: string;\n context: sourceParserContext;\n artifacts: TypedArtifactName[];\n option: CompilerOption | undefined;\n};\n\nexport function parseSingleSourceLine(\n logger: MiLogger,\n line: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n if (context.isInCommentBlock) {\n if (multilineCommentEndRE.exec(line)) {\n context.isInCommentBlock = false;\n }\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n if (compilerOptionRE.exec(line)) {\n if (!context.canDetectOptions) {\n logger.error(\n `[line ${context.lineNo}]: compiler option '//tengo:' was detected, but it cannot be applied as compiler options can be set only at the file header, before any code line'`,\n );\n throw new Error(\n \"tengo compiler options ('//tengo:' comments) can be set only in file header\",\n );\n }\n return { line, context, artifacts: [], option: parseComplierOption(line) };\n }\n\n if (wrongCompilerOptionRE.exec(line) && context.canDetectOptions) {\n logger.warn(\n `[line ${context.lineNo}]: text simillar to compiler option ('//tengo:...') was detected, but it has wrong format. Leave it as is, if you did not mean to use a line as compiler option. Or format it to '//tengo:<option>' otherwise (no spaces between '//' and 'tengo', no spaces between ':' and option name)`,\n );\n return { line, context, artifacts: [], option: undefined };\n }\n\n if (singlelineCommentRE.test(line) || singlelineTerminatedCommentRE.test(line)) {\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n const canBeInlinedComment = line.includes(\"*/\");\n if (multilineCommentStartRE.exec(line) && !canBeInlinedComment) {\n context.isInCommentBlock = true;\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n const statement = context.multilineStatement + line.trim();\n\n const mayContainAComment = line.includes(\"//\") || line.includes(\"/*\");\n if (multilineStatementRE.test(line) && !mayContainAComment) {\n // We accumulate multiline statements into single line before analyzing them.\n // This dramatically simplifies parsing logic: things like\n //\n // assets.\n // importSoftware(\"a:b\");\n //\n // become simple 'assets.importSoftware(\"a:b\");' for parser checks.\n //\n // For safety reasons, we never consider anything that 'may look like a comment'\n // as a part of multiline statement to prevent joining things like\n //\n // someFnCall() // looks like multiline statement because of dot in the end of a comment.\n //\n // This problem also appears in multiline string literals, but I hope this will not\n // cause problems in real life.\n\n // We still try to process each line to globalize imports in case of complex constructions, when\n // statements are stacked one into another:\n // a.\n // use(assets.importSoftware(\":soft1\")).\n // use(assets.importSoftware(\":soft2\")).\n // run()\n // It is multiline, and it still requires import globalization mid-way, not just for the last line of statement\n const result = processAssetImport(line, statement, context, localPackageName, globalizeImports);\n context.multilineStatement += result.line.trim(); // accumulate the line after imports globalization.\n return result;\n }\n\n context.multilineStatement = \"\"; // reset accumulated multiline statement parts once we reach statement end.\n\n if (emptyLineRE.exec(statement)) {\n return { line, context, artifacts: [], option: undefined };\n }\n\n // options could be only at the top of the file.\n context.canDetectOptions = false;\n\n return processAssetImport(line, statement, context, localPackageName, globalizeImports);\n}\n\nfunction processModuleImport(\n importInstruction: RegExpExecArray,\n originalLine: string,\n statement: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n const iInfo = parseImport(statement);\n\n // If we have plapi, ll or assets, then try to parse\n // getTemplateId, getSoftwareInfo, getSoftware and getAsset calls.\n\n if (iInfo.module === \"plapi\") {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newGetTemplateIdRE(iInfo.alias)],\n [\"software\", newGetSoftwareInfoRE(iInfo.alias)],\n ]);\n }\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n if (\n iInfo.module === \"@milaboratory/tengo-sdk:ll\" ||\n iInfo.module === \"@platforma-sdk/workflow-tengo:ll\" ||\n ((localPackageName === \"@milaboratory/tengo-sdk\" ||\n localPackageName === \"@platforma-sdk/workflow-tengo\") &&\n iInfo.module === \":ll\")\n ) {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newImportTemplateRE(iInfo.alias)],\n [\"software\", newImportSoftwareRE(iInfo.alias)],\n ]);\n }\n }\n\n if (\n iInfo.module === \"@milaboratory/tengo-sdk:assets\" ||\n iInfo.module === \"@platforma-sdk/workflow-tengo:assets\" ||\n ((localPackageName === \"@milaboratory/tengo-sdk\" ||\n localPackageName === \"@platforma-sdk/workflow-tengo\") &&\n iInfo.module === \":assets\")\n ) {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newImportTemplateRE(iInfo.alias)],\n [\"software\", newImportSoftwareRE(iInfo.alias)],\n [\"asset\", newImportAssetRE(iInfo.alias)],\n ]);\n context.importLikeREs.set(iInfo.module, [\n [\"template\", newImportTemplateDetector(iInfo.alias)],\n [\"software\", newImportSoftwareDetector(iInfo.alias)],\n [\"asset\", newImportAssetDetector(iInfo.alias)],\n ]);\n }\n }\n\n const artifact = parseArtifactName(iInfo.module, \"library\", localPackageName);\n if (!artifact) {\n // not a Platforma Tengo library import\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n if (globalizeImports) {\n originalLine = originalLine.replace(\n importInstruction[0],\n ` := import(\"${artifact.pkg}:${artifact.id}\")`,\n );\n }\n\n return { line: originalLine, context, artifacts: [artifact], option: undefined };\n}\n\nfunction processAssetImport(\n originalLine: string,\n statement: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n if (emptyLineRE.exec(statement)) {\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n // options could be only at the top of the file.\n context.canDetectOptions = false;\n\n const importInstruction = importRE.exec(statement);\n\n if (importInstruction) {\n return processModuleImport(\n importInstruction,\n originalLine,\n statement,\n context,\n localPackageName,\n globalizeImports,\n );\n }\n\n if (context.artifactImportREs.size > 0) {\n for (const [_, artifactRE] of context.artifactImportREs) {\n for (const [artifactType, re] of artifactRE) {\n // Find all matches in the statement\n const matches = Array.from(statement.matchAll(re));\n if (matches.length === 0) {\n continue;\n }\n\n const artifacts: TypedArtifactName[] = [];\n for (let i = matches.length - 1; i >= 0; i--) {\n const match = matches[i];\n if (!match || !match.groups) {\n continue;\n }\n\n const { fnCall, templateName, fnName } = match.groups;\n\n if (!fnCall || !templateName || !fnName) {\n throw Error(`failed to parse template import statement`);\n }\n\n const artifact = parseArtifactName(templateName, artifactType, localPackageName);\n if (!artifact) {\n throw Error(`failed to parse artifact name in ${fnName} import statement`);\n }\n artifacts.push(artifact);\n\n if (globalizeImports) {\n // Replace all occurrences of this fnCall in originalLine\n originalLine = originalLine.replaceAll(\n fnCall,\n `${fnName}(\"${artifact.pkg}:${artifact.id}\")`,\n );\n }\n }\n\n return { line: originalLine, context, artifacts, option: undefined };\n }\n }\n }\n\n if (context.importLikeREs.size > 0) {\n for (const [_, artifactRE] of context.importLikeREs) {\n for (const [artifactType, re] of artifactRE) {\n const match = re.exec(statement);\n if (!match || !match.groups) {\n continue;\n }\n\n throw Error(\n `incorrect '${artifactType}' import statement: use string literal as ID (variables are not allowed) in the same line with brackets (i.e. 'importSoftware(\"sw:main\")').`,\n );\n }\n }\n }\n\n return { line: originalLine, context, artifacts: [], option: undefined };\n}\n\ninterface ImportInfo {\n module: string; // the module name without wrapping quotes: import(\"<module>\")\n alias: string; // the name of variable that keeps imported module: <alias> := import(\"<module>\")\n}\n\nfunction parseImport(line: string): ImportInfo {\n const match = importNameRE.exec(line);\n\n if (!match || !match.groups) {\n throw Error(`failed to parse 'import' statement`);\n }\n\n const { importName, moduleName } = match.groups;\n if (!importName || !moduleName) {\n throw Error(`failed to parse 'import' statement`);\n }\n\n return {\n module: moduleName, // the module name without wrapping quotes: import(\"<module>\")\n alias: importName, // the name of variable that keeps imported module: <alias> := import(\"<module>\")\n };\n}\n\nfunction parseArtifactName(\n moduleName: string,\n aType: ArtifactType,\n localPackageName: string,\n): TypedArtifactName | undefined {\n const depInfo = dependencyRE.exec(moduleName);\n if (!depInfo) {\n return;\n }\n\n if (!depInfo.groups) {\n throw Error(\n `failed to parse dependency name inside 'import' statement. The dependency name should have format '<package>:<templateName>'`,\n );\n }\n\n const { pkgName, depID } = depInfo.groups;\n if (!depID) {\n throw Error(\n `failed to parse dependency name inside 'import' statement. The dependency name should have format '<package>:<templateName>'`,\n );\n }\n\n return { type: aType, pkg: pkgName ?? localPackageName, id: depID };\n}\n\nexport function getSha256(source: string): string {\n return createHash(\"sha256\").update(source).digest(\"hex\");\n}\n"],"mappings":"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"}
|
package/dist/compiler/source.js
CHANGED
|
@@ -2,7 +2,6 @@ import { fullNameToString } from "./package.js";
|
|
|
2
2
|
import { createArtifactNameSet } from "./artifactset.js";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
|
-
|
|
6
5
|
//#region src/compiler/source.ts
|
|
7
6
|
const namePattern = "[_a-zA-Z][_a-zA-Z0-9]*";
|
|
8
7
|
const functionCallRE = (moduleName, fnName) => {
|
|
@@ -276,7 +275,7 @@ function parseArtifactName(moduleName, aType, localPackageName) {
|
|
|
276
275
|
function getSha256(source) {
|
|
277
276
|
return createHash("sha256").update(source).digest("hex");
|
|
278
277
|
}
|
|
279
|
-
|
|
280
278
|
//#endregion
|
|
281
279
|
export { ArtifactSource, getSha256, parseSourceFile };
|
|
280
|
+
|
|
282
281
|
//# sourceMappingURL=source.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source.js","names":[],"sources":["../../src/compiler/source.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport {\n type TypedArtifactName,\n type FullArtifactName,\n type ArtifactType,\n type CompileMode,\n type CompilerOption,\n fullNameToString,\n} from \"./package\";\nimport type { ArtifactMap } from \"./artifactset\";\nimport { createArtifactNameSet } from \"./artifactset\";\nimport { createHash } from \"node:crypto\";\nimport type { MiLogger } from \"@milaboratories/ts-helpers\";\n\n// matches any valid name in tengo. Don't forget to use '\\b' when needed to limit the boundaries!\nconst namePattern = \"[_a-zA-Z][_a-zA-Z0-9]*\";\n\nconst functionCallRE = (moduleName: string, fnName: string) => {\n return new RegExp(\n `\\\\b${moduleName}\\\\.(?<fnCall>(?<fnName>` +\n fnName +\n `)\\\\s*\\\\(\\\\s*\"(?<templateName>[^\"]+)\"\\\\s*\\\\))`,\n \"g\",\n );\n};\n\nconst functionCallLikeRE = (moduleName: string, fnName: string) => {\n return new RegExp(`\\\\b${moduleName}\\\\.(?<fnName>` + fnName + `)\\\\s*\\\\(`, \"g\");\n};\n\nexport const newGetTemplateIdRE = (moduleName: string) =>\n functionCallRE(moduleName, \"getTemplateId\");\nexport const newGetSoftwareInfoRE = (moduleName: string) =>\n functionCallRE(moduleName, \"getSoftwareInfo\");\n\nconst newImportTemplateRE = (moduleName: string) => functionCallRE(moduleName, \"importTemplate\");\nconst newImportTemplateDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importTemplate\");\nconst newImportSoftwareRE = (moduleName: string) => functionCallRE(moduleName, \"importSoftware\");\nconst newImportSoftwareDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importSoftware\");\nconst newImportAssetRE = (moduleName: string) => functionCallRE(moduleName, \"importAsset\");\nconst newImportAssetDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importAsset\");\n\nconst emptyLineRE = /^\\s*$/;\nconst compilerOptionRE = /^\\/\\/tengo:[\\w]/;\nconst wrongCompilerOptionRE = /^\\s*\\/\\/\\s*tengo:\\s*./;\nconst singlelineCommentRE = /^\\s*(\\/\\/)/;\nconst singlelineTerminatedCommentRE = /^\\s*\\/\\*.*\\*\\/\\s*$/; // matches '^/* ... */$' comment lines as a special case of singleline comments.\nconst multilineCommentStartRE = /^\\s*\\/\\*/;\nconst multilineCommentEndRE = /\\*\\//;\nconst multilineStatementRE = /[.,]\\s*$/; // it is hard to consistently treat (\\n\"a\"\\n) multiline statements, we forbid them for now.\n\n// import could only be an assignment in a statement,\n// other ways could break a compilation.\nconst importRE = /\\s*:=\\s*import\\s*\\(\\s*\"(?<moduleName>[^\"]+)\"\\s*\\)/;\nconst importNameRE = new RegExp(\n `\\\\b(?<importName>${namePattern}(\\\\.${namePattern})*)${importRE.source}`,\n);\nconst dependencyRE = /(?<pkgName>[^\"]+)?:(?<depID>[^\"]+)/; // use it to parse <moduleName> from importPattern or <templateName> from getTemplateID\n\n/**\n * Parse compiler option string representation\n * Compiler option line is a comment starting with '//tengo:', say\n * //tengo:hash_override tralala\n *\n * The common compiler option syntax is:\n * //tengo:<option name> [<option arg1> [<option arg 2> [...]]]\n */\nconst parseComplierOption = (opt: string): CompilerOption => {\n const parts = opt.split(\" \");\n const namePart = parts[0].split(\":\");\n if (namePart.length != 2) {\n throw new Error(\n \"compiler option format is wrong: expect to have option name after 'tengo:' prefix, like 'tengo:MyOption'\",\n );\n }\n const optName = namePart[1];\n\n return {\n name: optName,\n args: parts.slice(1),\n };\n};\n\nexport class ArtifactSource {\n constructor(\n /** The mode this artifact was built (dev or dist) */\n public readonly compileMode: CompileMode,\n /** Full artifact id, including package version */\n public readonly fullName: FullArtifactName,\n /** Hash of the source code */\n public readonly sourceHash: string,\n /** Normalized source code */\n public readonly src: string,\n /** Path to source file where artifact came from */\n public readonly srcName: string,\n /** List of dependencies */\n public readonly dependencies: TypedArtifactName[],\n /** Additional compiler options detected in source code */\n public readonly compilerOptions: CompilerOption[],\n ) {}\n}\n\nexport function parseSourceFile(\n logger: MiLogger,\n mode: CompileMode,\n srcFile: string,\n fullSourceName: FullArtifactName,\n normalize: boolean,\n): ArtifactSource {\n const src = readFileSync(srcFile).toString();\n const { deps, normalized, opts } = parseSourceData(logger, src, fullSourceName, normalize);\n\n return new ArtifactSource(\n mode,\n fullSourceName,\n getSha256(normalized),\n normalized,\n srcFile,\n deps.array,\n opts,\n );\n}\n\nexport function parseSource(\n logger: MiLogger,\n mode: CompileMode,\n src: string,\n fullSourceName: FullArtifactName,\n normalize: boolean,\n): ArtifactSource {\n const { deps, normalized, opts } = parseSourceData(logger, src, fullSourceName, normalize);\n\n return new ArtifactSource(\n mode,\n fullSourceName,\n getSha256(normalized),\n normalized,\n \"\",\n deps.array,\n opts,\n );\n}\n\n/**\n * Reads src\n * returns normalized source code,\n * gets dependencies from imports,\n * maps imports to global names if globalizeImports is true,\n * and collects compiler options like hashOverride.\n */\nfunction parseSourceData(\n logger: MiLogger,\n src: string,\n fullSourceName: FullArtifactName,\n globalizeImports: boolean,\n): {\n normalized: string;\n deps: ArtifactMap<TypedArtifactName>;\n opts: CompilerOption[];\n} {\n const dependencySet = createArtifactNameSet();\n const optionList: CompilerOption[] = [];\n\n // iterating over lines\n const lines = src.split(\"\\n\");\n\n // processedLines keep all the original lines from <src>.\n // If <globalizeImport>==true, the parser modifies 'import' and 'getTemplateId' lines\n // with Platforma Tengo lib and template usages, resolving local names (\":<item>\") to\n // global (\"@milaboratory/pkg:<item>\")\n const processedLines: string[] = [];\n let parserContext: sourceParserContext = {\n isInCommentBlock: false,\n canDetectOptions: true,\n artifactImportREs: new Map<string, [ArtifactType, RegExp][]>(),\n importLikeREs: new Map<string, [ArtifactType, RegExp][]>(),\n multilineStatement: \"\",\n lineNo: 0,\n };\n\n for (const line of lines) {\n parserContext.lineNo++;\n\n try {\n const {\n line: processedLine,\n context: newContext,\n artifacts,\n option,\n } = parseSingleSourceLine(logger, line, parserContext, fullSourceName.pkg, globalizeImports);\n processedLines.push(processedLine);\n parserContext = newContext;\n\n for (const artifact of artifacts ?? []) {\n dependencySet.add(artifact);\n }\n if (option) {\n optionList.push(option);\n }\n } catch (error: unknown) {\n const err = error as Error;\n throw new Error(\n `[line ${parserContext.lineNo} in ${fullNameToString(fullSourceName)}]: ${err.message}\\n\\t${line}`,\n { cause: err },\n );\n }\n }\n\n return {\n normalized: processedLines.join(\"\\n\"),\n deps: dependencySet,\n opts: optionList,\n };\n}\n\nexport type sourceParserContext = {\n isInCommentBlock: boolean;\n canDetectOptions: boolean;\n artifactImportREs: Map<string, [ArtifactType, RegExp][]>;\n importLikeREs: Map<string, [ArtifactType, RegExp][]>;\n multilineStatement: string;\n lineNo: number;\n};\n\nexport type lineProcessingResult = {\n line: string;\n context: sourceParserContext;\n artifacts: TypedArtifactName[];\n option: CompilerOption | undefined;\n};\n\nexport function parseSingleSourceLine(\n logger: MiLogger,\n line: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n if (context.isInCommentBlock) {\n if (multilineCommentEndRE.exec(line)) {\n context.isInCommentBlock = false;\n }\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n if (compilerOptionRE.exec(line)) {\n if (!context.canDetectOptions) {\n logger.error(\n `[line ${context.lineNo}]: compiler option '//tengo:' was detected, but it cannot be applied as compiler options can be set only at the file header, before any code line'`,\n );\n throw new Error(\n \"tengo compiler options ('//tengo:' comments) can be set only in file header\",\n );\n }\n return { line, context, artifacts: [], option: parseComplierOption(line) };\n }\n\n if (wrongCompilerOptionRE.exec(line) && context.canDetectOptions) {\n logger.warn(\n `[line ${context.lineNo}]: text simillar to compiler option ('//tengo:...') was detected, but it has wrong format. Leave it as is, if you did not mean to use a line as compiler option. Or format it to '//tengo:<option>' otherwise (no spaces between '//' and 'tengo', no spaces between ':' and option name)`,\n );\n return { line, context, artifacts: [], option: undefined };\n }\n\n if (singlelineCommentRE.test(line) || singlelineTerminatedCommentRE.test(line)) {\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n const canBeInlinedComment = line.includes(\"*/\");\n if (multilineCommentStartRE.exec(line) && !canBeInlinedComment) {\n context.isInCommentBlock = true;\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n const statement = context.multilineStatement + line.trim();\n\n const mayContainAComment = line.includes(\"//\") || line.includes(\"/*\");\n if (multilineStatementRE.test(line) && !mayContainAComment) {\n // We accumulate multiline statements into single line before analyzing them.\n // This dramatically simplifies parsing logic: things like\n //\n // assets.\n // importSoftware(\"a:b\");\n //\n // become simple 'assets.importSoftware(\"a:b\");' for parser checks.\n //\n // For safety reasons, we never consider anything that 'may look like a comment'\n // as a part of multiline statement to prevent joining things like\n //\n // someFnCall() // looks like multiline statement because of dot in the end of a comment.\n //\n // This problem also appears in multiline string literals, but I hope this will not\n // cause problems in real life.\n\n // We still try to process each line to globalize imports in case of complex constructions, when\n // statements are stacked one into another:\n // a.\n // use(assets.importSoftware(\":soft1\")).\n // use(assets.importSoftware(\":soft2\")).\n // run()\n // It is multiline, and it still requires import globalization mid-way, not just for the last line of statement\n const result = processAssetImport(line, statement, context, localPackageName, globalizeImports);\n context.multilineStatement += result.line.trim(); // accumulate the line after imports globalization.\n return result;\n }\n\n context.multilineStatement = \"\"; // reset accumulated multiline statement parts once we reach statement end.\n\n if (emptyLineRE.exec(statement)) {\n return { line, context, artifacts: [], option: undefined };\n }\n\n // options could be only at the top of the file.\n context.canDetectOptions = false;\n\n return processAssetImport(line, statement, context, localPackageName, globalizeImports);\n}\n\nfunction processModuleImport(\n importInstruction: RegExpExecArray,\n originalLine: string,\n statement: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n const iInfo = parseImport(statement);\n\n // If we have plapi, ll or assets, then try to parse\n // getTemplateId, getSoftwareInfo, getSoftware and getAsset calls.\n\n if (iInfo.module === \"plapi\") {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newGetTemplateIdRE(iInfo.alias)],\n [\"software\", newGetSoftwareInfoRE(iInfo.alias)],\n ]);\n }\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n if (\n iInfo.module === \"@milaboratory/tengo-sdk:ll\" ||\n iInfo.module === \"@platforma-sdk/workflow-tengo:ll\" ||\n ((localPackageName === \"@milaboratory/tengo-sdk\" ||\n localPackageName === \"@platforma-sdk/workflow-tengo\") &&\n iInfo.module === \":ll\")\n ) {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newImportTemplateRE(iInfo.alias)],\n [\"software\", newImportSoftwareRE(iInfo.alias)],\n ]);\n }\n }\n\n if (\n iInfo.module === \"@milaboratory/tengo-sdk:assets\" ||\n iInfo.module === \"@platforma-sdk/workflow-tengo:assets\" ||\n ((localPackageName === \"@milaboratory/tengo-sdk\" ||\n localPackageName === \"@platforma-sdk/workflow-tengo\") &&\n iInfo.module === \":assets\")\n ) {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newImportTemplateRE(iInfo.alias)],\n [\"software\", newImportSoftwareRE(iInfo.alias)],\n [\"asset\", newImportAssetRE(iInfo.alias)],\n ]);\n context.importLikeREs.set(iInfo.module, [\n [\"template\", newImportTemplateDetector(iInfo.alias)],\n [\"software\", newImportSoftwareDetector(iInfo.alias)],\n [\"asset\", newImportAssetDetector(iInfo.alias)],\n ]);\n }\n }\n\n const artifact = parseArtifactName(iInfo.module, \"library\", localPackageName);\n if (!artifact) {\n // not a Platforma Tengo library import\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n if (globalizeImports) {\n originalLine = originalLine.replace(\n importInstruction[0],\n ` := import(\"${artifact.pkg}:${artifact.id}\")`,\n );\n }\n\n return { line: originalLine, context, artifacts: [artifact], option: undefined };\n}\n\nfunction processAssetImport(\n originalLine: string,\n statement: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n if (emptyLineRE.exec(statement)) {\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n // options could be only at the top of the file.\n context.canDetectOptions = false;\n\n const importInstruction = importRE.exec(statement);\n\n if (importInstruction) {\n return processModuleImport(\n importInstruction,\n originalLine,\n statement,\n context,\n localPackageName,\n globalizeImports,\n );\n }\n\n if (context.artifactImportREs.size > 0) {\n for (const [_, artifactRE] of context.artifactImportREs) {\n for (const [artifactType, re] of artifactRE) {\n // Find all matches in the statement\n const matches = Array.from(statement.matchAll(re));\n if (matches.length === 0) {\n continue;\n }\n\n const artifacts: TypedArtifactName[] = [];\n for (let i = matches.length - 1; i >= 0; i--) {\n const match = matches[i];\n if (!match || !match.groups) {\n continue;\n }\n\n const { fnCall, templateName, fnName } = match.groups;\n\n if (!fnCall || !templateName || !fnName) {\n throw Error(`failed to parse template import statement`);\n }\n\n const artifact = parseArtifactName(templateName, artifactType, localPackageName);\n if (!artifact) {\n throw Error(`failed to parse artifact name in ${fnName} import statement`);\n }\n artifacts.push(artifact);\n\n if (globalizeImports) {\n // Replace all occurrences of this fnCall in originalLine\n originalLine = originalLine.replaceAll(\n fnCall,\n `${fnName}(\"${artifact.pkg}:${artifact.id}\")`,\n );\n }\n }\n\n return { line: originalLine, context, artifacts, option: undefined };\n }\n }\n }\n\n if (context.importLikeREs.size > 0) {\n for (const [_, artifactRE] of context.importLikeREs) {\n for (const [artifactType, re] of artifactRE) {\n const match = re.exec(statement);\n if (!match || !match.groups) {\n continue;\n }\n\n throw Error(\n `incorrect '${artifactType}' import statement: use string literal as ID (variables are not allowed) in the same line with brackets (i.e. 'importSoftware(\"sw:main\")').`,\n );\n }\n }\n }\n\n return { line: originalLine, context, artifacts: [], option: undefined };\n}\n\ninterface ImportInfo {\n module: string; // the module name without wrapping quotes: import(\"<module>\")\n alias: string; // the name of variable that keeps imported module: <alias> := import(\"<module>\")\n}\n\nfunction parseImport(line: string): ImportInfo {\n const match = importNameRE.exec(line);\n\n if (!match || !match.groups) {\n throw Error(`failed to parse 'import' statement`);\n }\n\n const { importName, moduleName } = match.groups;\n if (!importName || !moduleName) {\n throw Error(`failed to parse 'import' statement`);\n }\n\n return {\n module: moduleName, // the module name without wrapping quotes: import(\"<module>\")\n alias: importName, // the name of variable that keeps imported module: <alias> := import(\"<module>\")\n };\n}\n\nfunction parseArtifactName(\n moduleName: string,\n aType: ArtifactType,\n localPackageName: string,\n): TypedArtifactName | undefined {\n const depInfo = dependencyRE.exec(moduleName);\n if (!depInfo) {\n return;\n }\n\n if (!depInfo.groups) {\n throw Error(\n `failed to parse dependency name inside 'import' statement. The dependency name should have format '<package>:<templateName>'`,\n );\n }\n\n const { pkgName, depID } = depInfo.groups;\n if (!depID) {\n throw Error(\n `failed to parse dependency name inside 'import' statement. The dependency name should have format '<package>:<templateName>'`,\n );\n }\n\n return { type: aType, pkg: pkgName ?? localPackageName, id: depID };\n}\n\nexport function getSha256(source: string): string {\n return createHash(\"sha256\").update(source).digest(\"hex\");\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"source.js","names":[],"sources":["../../src/compiler/source.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport {\n type TypedArtifactName,\n type FullArtifactName,\n type ArtifactType,\n type CompileMode,\n type CompilerOption,\n fullNameToString,\n} from \"./package\";\nimport type { ArtifactMap } from \"./artifactset\";\nimport { createArtifactNameSet } from \"./artifactset\";\nimport { createHash } from \"node:crypto\";\nimport type { MiLogger } from \"@milaboratories/ts-helpers\";\n\n// matches any valid name in tengo. Don't forget to use '\\b' when needed to limit the boundaries!\nconst namePattern = \"[_a-zA-Z][_a-zA-Z0-9]*\";\n\nconst functionCallRE = (moduleName: string, fnName: string) => {\n return new RegExp(\n `\\\\b${moduleName}\\\\.(?<fnCall>(?<fnName>` +\n fnName +\n `)\\\\s*\\\\(\\\\s*\"(?<templateName>[^\"]+)\"\\\\s*\\\\))`,\n \"g\",\n );\n};\n\nconst functionCallLikeRE = (moduleName: string, fnName: string) => {\n return new RegExp(`\\\\b${moduleName}\\\\.(?<fnName>` + fnName + `)\\\\s*\\\\(`, \"g\");\n};\n\nexport const newGetTemplateIdRE = (moduleName: string) =>\n functionCallRE(moduleName, \"getTemplateId\");\nexport const newGetSoftwareInfoRE = (moduleName: string) =>\n functionCallRE(moduleName, \"getSoftwareInfo\");\n\nconst newImportTemplateRE = (moduleName: string) => functionCallRE(moduleName, \"importTemplate\");\nconst newImportTemplateDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importTemplate\");\nconst newImportSoftwareRE = (moduleName: string) => functionCallRE(moduleName, \"importSoftware\");\nconst newImportSoftwareDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importSoftware\");\nconst newImportAssetRE = (moduleName: string) => functionCallRE(moduleName, \"importAsset\");\nconst newImportAssetDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importAsset\");\n\nconst emptyLineRE = /^\\s*$/;\nconst compilerOptionRE = /^\\/\\/tengo:[\\w]/;\nconst wrongCompilerOptionRE = /^\\s*\\/\\/\\s*tengo:\\s*./;\nconst singlelineCommentRE = /^\\s*(\\/\\/)/;\nconst singlelineTerminatedCommentRE = /^\\s*\\/\\*.*\\*\\/\\s*$/; // matches '^/* ... */$' comment lines as a special case of singleline comments.\nconst multilineCommentStartRE = /^\\s*\\/\\*/;\nconst multilineCommentEndRE = /\\*\\//;\nconst multilineStatementRE = /[.,]\\s*$/; // it is hard to consistently treat (\\n\"a\"\\n) multiline statements, we forbid them for now.\n\n// import could only be an assignment in a statement,\n// other ways could break a compilation.\nconst importRE = /\\s*:=\\s*import\\s*\\(\\s*\"(?<moduleName>[^\"]+)\"\\s*\\)/;\nconst importNameRE = new RegExp(\n `\\\\b(?<importName>${namePattern}(\\\\.${namePattern})*)${importRE.source}`,\n);\nconst dependencyRE = /(?<pkgName>[^\"]+)?:(?<depID>[^\"]+)/; // use it to parse <moduleName> from importPattern or <templateName> from getTemplateID\n\n/**\n * Parse compiler option string representation\n * Compiler option line is a comment starting with '//tengo:', say\n * //tengo:hash_override tralala\n *\n * The common compiler option syntax is:\n * //tengo:<option name> [<option arg1> [<option arg 2> [...]]]\n */\nconst parseComplierOption = (opt: string): CompilerOption => {\n const parts = opt.split(\" \");\n const namePart = parts[0].split(\":\");\n if (namePart.length != 2) {\n throw new Error(\n \"compiler option format is wrong: expect to have option name after 'tengo:' prefix, like 'tengo:MyOption'\",\n );\n }\n const optName = namePart[1];\n\n return {\n name: optName,\n args: parts.slice(1),\n };\n};\n\nexport class ArtifactSource {\n constructor(\n /** The mode this artifact was built (dev or dist) */\n public readonly compileMode: CompileMode,\n /** Full artifact id, including package version */\n public readonly fullName: FullArtifactName,\n /** Hash of the source code */\n public readonly sourceHash: string,\n /** Normalized source code */\n public readonly src: string,\n /** Path to source file where artifact came from */\n public readonly srcName: string,\n /** List of dependencies */\n public readonly dependencies: TypedArtifactName[],\n /** Additional compiler options detected in source code */\n public readonly compilerOptions: CompilerOption[],\n ) {}\n}\n\nexport function parseSourceFile(\n logger: MiLogger,\n mode: CompileMode,\n srcFile: string,\n fullSourceName: FullArtifactName,\n normalize: boolean,\n): ArtifactSource {\n const src = readFileSync(srcFile).toString();\n const { deps, normalized, opts } = parseSourceData(logger, src, fullSourceName, normalize);\n\n return new ArtifactSource(\n mode,\n fullSourceName,\n getSha256(normalized),\n normalized,\n srcFile,\n deps.array,\n opts,\n );\n}\n\nexport function parseSource(\n logger: MiLogger,\n mode: CompileMode,\n src: string,\n fullSourceName: FullArtifactName,\n normalize: boolean,\n): ArtifactSource {\n const { deps, normalized, opts } = parseSourceData(logger, src, fullSourceName, normalize);\n\n return new ArtifactSource(\n mode,\n fullSourceName,\n getSha256(normalized),\n normalized,\n \"\",\n deps.array,\n opts,\n );\n}\n\n/**\n * Reads src\n * returns normalized source code,\n * gets dependencies from imports,\n * maps imports to global names if globalizeImports is true,\n * and collects compiler options like hashOverride.\n */\nfunction parseSourceData(\n logger: MiLogger,\n src: string,\n fullSourceName: FullArtifactName,\n globalizeImports: boolean,\n): {\n normalized: string;\n deps: ArtifactMap<TypedArtifactName>;\n opts: CompilerOption[];\n} {\n const dependencySet = createArtifactNameSet();\n const optionList: CompilerOption[] = [];\n\n // iterating over lines\n const lines = src.split(\"\\n\");\n\n // processedLines keep all the original lines from <src>.\n // If <globalizeImport>==true, the parser modifies 'import' and 'getTemplateId' lines\n // with Platforma Tengo lib and template usages, resolving local names (\":<item>\") to\n // global (\"@milaboratory/pkg:<item>\")\n const processedLines: string[] = [];\n let parserContext: sourceParserContext = {\n isInCommentBlock: false,\n canDetectOptions: true,\n artifactImportREs: new Map<string, [ArtifactType, RegExp][]>(),\n importLikeREs: new Map<string, [ArtifactType, RegExp][]>(),\n multilineStatement: \"\",\n lineNo: 0,\n };\n\n for (const line of lines) {\n parserContext.lineNo++;\n\n try {\n const {\n line: processedLine,\n context: newContext,\n artifacts,\n option,\n } = parseSingleSourceLine(logger, line, parserContext, fullSourceName.pkg, globalizeImports);\n processedLines.push(processedLine);\n parserContext = newContext;\n\n for (const artifact of artifacts ?? []) {\n dependencySet.add(artifact);\n }\n if (option) {\n optionList.push(option);\n }\n } catch (error: unknown) {\n const err = error as Error;\n throw new Error(\n `[line ${parserContext.lineNo} in ${fullNameToString(fullSourceName)}]: ${err.message}\\n\\t${line}`,\n { cause: err },\n );\n }\n }\n\n return {\n normalized: processedLines.join(\"\\n\"),\n deps: dependencySet,\n opts: optionList,\n };\n}\n\nexport type sourceParserContext = {\n isInCommentBlock: boolean;\n canDetectOptions: boolean;\n artifactImportREs: Map<string, [ArtifactType, RegExp][]>;\n importLikeREs: Map<string, [ArtifactType, RegExp][]>;\n multilineStatement: string;\n lineNo: number;\n};\n\nexport type lineProcessingResult = {\n line: string;\n context: sourceParserContext;\n artifacts: TypedArtifactName[];\n option: CompilerOption | undefined;\n};\n\nexport function parseSingleSourceLine(\n logger: MiLogger,\n line: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n if (context.isInCommentBlock) {\n if (multilineCommentEndRE.exec(line)) {\n context.isInCommentBlock = false;\n }\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n if (compilerOptionRE.exec(line)) {\n if (!context.canDetectOptions) {\n logger.error(\n `[line ${context.lineNo}]: compiler option '//tengo:' was detected, but it cannot be applied as compiler options can be set only at the file header, before any code line'`,\n );\n throw new Error(\n \"tengo compiler options ('//tengo:' comments) can be set only in file header\",\n );\n }\n return { line, context, artifacts: [], option: parseComplierOption(line) };\n }\n\n if (wrongCompilerOptionRE.exec(line) && context.canDetectOptions) {\n logger.warn(\n `[line ${context.lineNo}]: text simillar to compiler option ('//tengo:...') was detected, but it has wrong format. Leave it as is, if you did not mean to use a line as compiler option. Or format it to '//tengo:<option>' otherwise (no spaces between '//' and 'tengo', no spaces between ':' and option name)`,\n );\n return { line, context, artifacts: [], option: undefined };\n }\n\n if (singlelineCommentRE.test(line) || singlelineTerminatedCommentRE.test(line)) {\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n const canBeInlinedComment = line.includes(\"*/\");\n if (multilineCommentStartRE.exec(line) && !canBeInlinedComment) {\n context.isInCommentBlock = true;\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n const statement = context.multilineStatement + line.trim();\n\n const mayContainAComment = line.includes(\"//\") || line.includes(\"/*\");\n if (multilineStatementRE.test(line) && !mayContainAComment) {\n // We accumulate multiline statements into single line before analyzing them.\n // This dramatically simplifies parsing logic: things like\n //\n // assets.\n // importSoftware(\"a:b\");\n //\n // become simple 'assets.importSoftware(\"a:b\");' for parser checks.\n //\n // For safety reasons, we never consider anything that 'may look like a comment'\n // as a part of multiline statement to prevent joining things like\n //\n // someFnCall() // looks like multiline statement because of dot in the end of a comment.\n //\n // This problem also appears in multiline string literals, but I hope this will not\n // cause problems in real life.\n\n // We still try to process each line to globalize imports in case of complex constructions, when\n // statements are stacked one into another:\n // a.\n // use(assets.importSoftware(\":soft1\")).\n // use(assets.importSoftware(\":soft2\")).\n // run()\n // It is multiline, and it still requires import globalization mid-way, not just for the last line of statement\n const result = processAssetImport(line, statement, context, localPackageName, globalizeImports);\n context.multilineStatement += result.line.trim(); // accumulate the line after imports globalization.\n return result;\n }\n\n context.multilineStatement = \"\"; // reset accumulated multiline statement parts once we reach statement end.\n\n if (emptyLineRE.exec(statement)) {\n return { line, context, artifacts: [], option: undefined };\n }\n\n // options could be only at the top of the file.\n context.canDetectOptions = false;\n\n return processAssetImport(line, statement, context, localPackageName, globalizeImports);\n}\n\nfunction processModuleImport(\n importInstruction: RegExpExecArray,\n originalLine: string,\n statement: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n const iInfo = parseImport(statement);\n\n // If we have plapi, ll or assets, then try to parse\n // getTemplateId, getSoftwareInfo, getSoftware and getAsset calls.\n\n if (iInfo.module === \"plapi\") {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newGetTemplateIdRE(iInfo.alias)],\n [\"software\", newGetSoftwareInfoRE(iInfo.alias)],\n ]);\n }\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n if (\n iInfo.module === \"@milaboratory/tengo-sdk:ll\" ||\n iInfo.module === \"@platforma-sdk/workflow-tengo:ll\" ||\n ((localPackageName === \"@milaboratory/tengo-sdk\" ||\n localPackageName === \"@platforma-sdk/workflow-tengo\") &&\n iInfo.module === \":ll\")\n ) {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newImportTemplateRE(iInfo.alias)],\n [\"software\", newImportSoftwareRE(iInfo.alias)],\n ]);\n }\n }\n\n if (\n iInfo.module === \"@milaboratory/tengo-sdk:assets\" ||\n iInfo.module === \"@platforma-sdk/workflow-tengo:assets\" ||\n ((localPackageName === \"@milaboratory/tengo-sdk\" ||\n localPackageName === \"@platforma-sdk/workflow-tengo\") &&\n iInfo.module === \":assets\")\n ) {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newImportTemplateRE(iInfo.alias)],\n [\"software\", newImportSoftwareRE(iInfo.alias)],\n [\"asset\", newImportAssetRE(iInfo.alias)],\n ]);\n context.importLikeREs.set(iInfo.module, [\n [\"template\", newImportTemplateDetector(iInfo.alias)],\n [\"software\", newImportSoftwareDetector(iInfo.alias)],\n [\"asset\", newImportAssetDetector(iInfo.alias)],\n ]);\n }\n }\n\n const artifact = parseArtifactName(iInfo.module, \"library\", localPackageName);\n if (!artifact) {\n // not a Platforma Tengo library import\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n if (globalizeImports) {\n originalLine = originalLine.replace(\n importInstruction[0],\n ` := import(\"${artifact.pkg}:${artifact.id}\")`,\n );\n }\n\n return { line: originalLine, context, artifacts: [artifact], option: undefined };\n}\n\nfunction processAssetImport(\n originalLine: string,\n statement: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n if (emptyLineRE.exec(statement)) {\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n // options could be only at the top of the file.\n context.canDetectOptions = false;\n\n const importInstruction = importRE.exec(statement);\n\n if (importInstruction) {\n return processModuleImport(\n importInstruction,\n originalLine,\n statement,\n context,\n localPackageName,\n globalizeImports,\n );\n }\n\n if (context.artifactImportREs.size > 0) {\n for (const [_, artifactRE] of context.artifactImportREs) {\n for (const [artifactType, re] of artifactRE) {\n // Find all matches in the statement\n const matches = Array.from(statement.matchAll(re));\n if (matches.length === 0) {\n continue;\n }\n\n const artifacts: TypedArtifactName[] = [];\n for (let i = matches.length - 1; i >= 0; i--) {\n const match = matches[i];\n if (!match || !match.groups) {\n continue;\n }\n\n const { fnCall, templateName, fnName } = match.groups;\n\n if (!fnCall || !templateName || !fnName) {\n throw Error(`failed to parse template import statement`);\n }\n\n const artifact = parseArtifactName(templateName, artifactType, localPackageName);\n if (!artifact) {\n throw Error(`failed to parse artifact name in ${fnName} import statement`);\n }\n artifacts.push(artifact);\n\n if (globalizeImports) {\n // Replace all occurrences of this fnCall in originalLine\n originalLine = originalLine.replaceAll(\n fnCall,\n `${fnName}(\"${artifact.pkg}:${artifact.id}\")`,\n );\n }\n }\n\n return { line: originalLine, context, artifacts, option: undefined };\n }\n }\n }\n\n if (context.importLikeREs.size > 0) {\n for (const [_, artifactRE] of context.importLikeREs) {\n for (const [artifactType, re] of artifactRE) {\n const match = re.exec(statement);\n if (!match || !match.groups) {\n continue;\n }\n\n throw Error(\n `incorrect '${artifactType}' import statement: use string literal as ID (variables are not allowed) in the same line with brackets (i.e. 'importSoftware(\"sw:main\")').`,\n );\n }\n }\n }\n\n return { line: originalLine, context, artifacts: [], option: undefined };\n}\n\ninterface ImportInfo {\n module: string; // the module name without wrapping quotes: import(\"<module>\")\n alias: string; // the name of variable that keeps imported module: <alias> := import(\"<module>\")\n}\n\nfunction parseImport(line: string): ImportInfo {\n const match = importNameRE.exec(line);\n\n if (!match || !match.groups) {\n throw Error(`failed to parse 'import' statement`);\n }\n\n const { importName, moduleName } = match.groups;\n if (!importName || !moduleName) {\n throw Error(`failed to parse 'import' statement`);\n }\n\n return {\n module: moduleName, // the module name without wrapping quotes: import(\"<module>\")\n alias: importName, // the name of variable that keeps imported module: <alias> := import(\"<module>\")\n };\n}\n\nfunction parseArtifactName(\n moduleName: string,\n aType: ArtifactType,\n localPackageName: string,\n): TypedArtifactName | undefined {\n const depInfo = dependencyRE.exec(moduleName);\n if (!depInfo) {\n return;\n }\n\n if (!depInfo.groups) {\n throw Error(\n `failed to parse dependency name inside 'import' statement. The dependency name should have format '<package>:<templateName>'`,\n );\n }\n\n const { pkgName, depID } = depInfo.groups;\n if (!depID) {\n throw Error(\n `failed to parse dependency name inside 'import' statement. The dependency name should have format '<package>:<templateName>'`,\n );\n }\n\n return { type: aType, pkg: pkgName ?? localPackageName, id: depID };\n}\n\nexport function getSha256(source: string): string {\n return createHash(\"sha256\").update(source).digest(\"hex\");\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
const require_package = require(
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_package = require("./package.cjs");
|
|
3
3
|
let _milaboratories_pl_model_backend = require("@milaboratories/pl-model-backend");
|
|
4
|
-
|
|
5
4
|
//#region src/compiler/template.ts
|
|
6
5
|
function newTemplateWithSource(compileMode, fullName, data, source) {
|
|
7
6
|
validateTemplateName(fullName, data);
|
|
@@ -35,9 +34,9 @@ function validateTemplateName(fullName, data) {
|
|
|
35
34
|
const nameFromData = require_package.parseArtefactNameAndVersion(data.template);
|
|
36
35
|
if (nameFromData.pkg !== fullName.pkg || nameFromData.id !== fullName.id || nameFromData.version !== fullName.version) throw new Error(`Compiled template name don't match it's package and file names: ${require_package.fullNameWithoutTypeToString(nameFromData)} != ${require_package.fullNameWithoutTypeToString(fullName)}`);
|
|
37
36
|
}
|
|
38
|
-
|
|
39
37
|
//#endregion
|
|
40
38
|
exports.newTemplateFromContent = newTemplateFromContent;
|
|
41
39
|
exports.newTemplateWithSource = newTemplateWithSource;
|
|
42
40
|
exports.templateToSource = templateToSource;
|
|
41
|
+
|
|
43
42
|
//# sourceMappingURL=template.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.cjs","names":["parseArtefactNameAndVersion","fullNameWithoutTypeToString"],"sources":["../../src/compiler/template.ts"],"sourcesContent":["import type { CompileMode, FullArtifactName, FullArtifactNameWithoutType } from \"./package\";\nimport { fullNameWithoutTypeToString, parseArtefactNameAndVersion } from \"./package\";\nimport type { CompiledTemplateV3 } from \"@milaboratories/pl-model-backend\";\nimport { parseTemplate, serializeTemplate } from \"@milaboratories/pl-model-backend\";\n\n/** Just a holder for template data, compilation options, full name and source code.\n * It mimics ArtifactSource interface.\n */\nexport type TemplateWithSource = {\n readonly compileMode: CompileMode;\n readonly fullName: FullArtifactName;\n readonly source: string;\n readonly data: CompiledTemplateV3;\n};\n\nexport function newTemplateWithSource(\n compileMode: CompileMode,\n fullName: FullArtifactName,\n data: CompiledTemplateV3,\n source: string,\n): TemplateWithSource {\n validateTemplateName(fullName, data);\n\n return {\n compileMode,\n fullName,\n data,\n source,\n };\n}\n\nexport type Template = {\n readonly compileMode: CompileMode;\n readonly fullName: FullArtifactName;\n readonly data: CompiledTemplateV3;\n readonly content: Uint8Array;\n};\n\nexport function newTemplateFromData(\n compileMode: CompileMode,\n fullName: FullArtifactName,\n data: CompiledTemplateV3,\n): Template {\n validateTemplateName(fullName, data);\n return {\n compileMode,\n fullName,\n data,\n content: serializeTemplate(data),\n };\n}\n\nexport function newTemplateFromContent(\n compileMode: CompileMode,\n fullName: FullArtifactName,\n content: Uint8Array,\n): Template {\n const data = parseTemplate(content);\n if (data.type !== \"pl.tengo-template.v3\") {\n throw new Error(\"malformed v3 template\");\n }\n\n validateTemplateName(fullName, data);\n return {\n compileMode,\n fullName,\n data,\n content,\n };\n}\n\nexport function templateToSource(tpl: Template): TemplateWithSource {\n return {\n compileMode: tpl.compileMode,\n fullName: tpl.fullName,\n data: tpl.data,\n source: tpl.data.hashToSource[tpl.data.template.sourceHash],\n };\n}\nfunction validateTemplateName(fullName: FullArtifactName, data: CompiledTemplateV3) {\n const nameFromData: FullArtifactNameWithoutType = parseArtefactNameAndVersion(data.template);\n\n if (\n nameFromData.pkg !== fullName.pkg ||\n nameFromData.id !== fullName.id ||\n nameFromData.version !== fullName.version\n )\n throw new Error(\n `Compiled template name don't match it's package and file names: ` +\n `${fullNameWithoutTypeToString(nameFromData)} != ${fullNameWithoutTypeToString(fullName)}`,\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"template.cjs","names":["parseArtefactNameAndVersion","fullNameWithoutTypeToString"],"sources":["../../src/compiler/template.ts"],"sourcesContent":["import type { CompileMode, FullArtifactName, FullArtifactNameWithoutType } from \"./package\";\nimport { fullNameWithoutTypeToString, parseArtefactNameAndVersion } from \"./package\";\nimport type { CompiledTemplateV3 } from \"@milaboratories/pl-model-backend\";\nimport { parseTemplate, serializeTemplate } from \"@milaboratories/pl-model-backend\";\n\n/** Just a holder for template data, compilation options, full name and source code.\n * It mimics ArtifactSource interface.\n */\nexport type TemplateWithSource = {\n readonly compileMode: CompileMode;\n readonly fullName: FullArtifactName;\n readonly source: string;\n readonly data: CompiledTemplateV3;\n};\n\nexport function newTemplateWithSource(\n compileMode: CompileMode,\n fullName: FullArtifactName,\n data: CompiledTemplateV3,\n source: string,\n): TemplateWithSource {\n validateTemplateName(fullName, data);\n\n return {\n compileMode,\n fullName,\n data,\n source,\n };\n}\n\nexport type Template = {\n readonly compileMode: CompileMode;\n readonly fullName: FullArtifactName;\n readonly data: CompiledTemplateV3;\n readonly content: Uint8Array;\n};\n\nexport function newTemplateFromData(\n compileMode: CompileMode,\n fullName: FullArtifactName,\n data: CompiledTemplateV3,\n): Template {\n validateTemplateName(fullName, data);\n return {\n compileMode,\n fullName,\n data,\n content: serializeTemplate(data),\n };\n}\n\nexport function newTemplateFromContent(\n compileMode: CompileMode,\n fullName: FullArtifactName,\n content: Uint8Array,\n): Template {\n const data = parseTemplate(content);\n if (data.type !== \"pl.tengo-template.v3\") {\n throw new Error(\"malformed v3 template\");\n }\n\n validateTemplateName(fullName, data);\n return {\n compileMode,\n fullName,\n data,\n content,\n };\n}\n\nexport function templateToSource(tpl: Template): TemplateWithSource {\n return {\n compileMode: tpl.compileMode,\n fullName: tpl.fullName,\n data: tpl.data,\n source: tpl.data.hashToSource[tpl.data.template.sourceHash],\n };\n}\nfunction validateTemplateName(fullName: FullArtifactName, data: CompiledTemplateV3) {\n const nameFromData: FullArtifactNameWithoutType = parseArtefactNameAndVersion(data.template);\n\n if (\n nameFromData.pkg !== fullName.pkg ||\n nameFromData.id !== fullName.id ||\n nameFromData.version !== fullName.version\n )\n throw new Error(\n `Compiled template name don't match it's package and file names: ` +\n `${fullNameWithoutTypeToString(nameFromData)} != ${fullNameWithoutTypeToString(fullName)}`,\n );\n}\n"],"mappings":";;;;AAeA,SAAgB,sBACd,aACA,UACA,MACA,QACoB;AACpB,sBAAqB,UAAU,KAAK;AAEpC,QAAO;EACL;EACA;EACA;EACA;EACD;;AAwBH,SAAgB,uBACd,aACA,UACA,SACU;CACV,MAAM,QAAA,GAAA,iCAAA,eAAqB,QAAQ;AACnC,KAAI,KAAK,SAAS,uBAChB,OAAM,IAAI,MAAM,wBAAwB;AAG1C,sBAAqB,UAAU,KAAK;AACpC,QAAO;EACL;EACA;EACA;EACA;EACD;;AAGH,SAAgB,iBAAiB,KAAmC;AAClE,QAAO;EACL,aAAa,IAAI;EACjB,UAAU,IAAI;EACd,MAAM,IAAI;EACV,QAAQ,IAAI,KAAK,aAAa,IAAI,KAAK,SAAS;EACjD;;AAEH,SAAS,qBAAqB,UAA4B,MAA0B;CAClF,MAAM,eAA4CA,gBAAAA,4BAA4B,KAAK,SAAS;AAE5F,KACE,aAAa,QAAQ,SAAS,OAC9B,aAAa,OAAO,SAAS,MAC7B,aAAa,YAAY,SAAS,QAElC,OAAM,IAAI,MACR,mEACKC,gBAAAA,4BAA4B,aAAa,CAAC,MAAMA,gBAAAA,4BAA4B,SAAS,GAC3F"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { fullNameWithoutTypeToString, parseArtefactNameAndVersion } from "./package.js";
|
|
2
|
-
import { parseTemplate
|
|
3
|
-
|
|
2
|
+
import { parseTemplate } from "@milaboratories/pl-model-backend";
|
|
4
3
|
//#region src/compiler/template.ts
|
|
5
4
|
function newTemplateWithSource(compileMode, fullName, data, source) {
|
|
6
5
|
validateTemplateName(fullName, data);
|
|
@@ -34,7 +33,7 @@ function validateTemplateName(fullName, data) {
|
|
|
34
33
|
const nameFromData = parseArtefactNameAndVersion(data.template);
|
|
35
34
|
if (nameFromData.pkg !== fullName.pkg || nameFromData.id !== fullName.id || nameFromData.version !== fullName.version) throw new Error(`Compiled template name don't match it's package and file names: ${fullNameWithoutTypeToString(nameFromData)} != ${fullNameWithoutTypeToString(fullName)}`);
|
|
36
35
|
}
|
|
37
|
-
|
|
38
36
|
//#endregion
|
|
39
37
|
export { newTemplateFromContent, newTemplateWithSource, templateToSource };
|
|
38
|
+
|
|
40
39
|
//# sourceMappingURL=template.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","names":[],"sources":["../../src/compiler/template.ts"],"sourcesContent":["import type { CompileMode, FullArtifactName, FullArtifactNameWithoutType } from \"./package\";\nimport { fullNameWithoutTypeToString, parseArtefactNameAndVersion } from \"./package\";\nimport type { CompiledTemplateV3 } from \"@milaboratories/pl-model-backend\";\nimport { parseTemplate, serializeTemplate } from \"@milaboratories/pl-model-backend\";\n\n/** Just a holder for template data, compilation options, full name and source code.\n * It mimics ArtifactSource interface.\n */\nexport type TemplateWithSource = {\n readonly compileMode: CompileMode;\n readonly fullName: FullArtifactName;\n readonly source: string;\n readonly data: CompiledTemplateV3;\n};\n\nexport function newTemplateWithSource(\n compileMode: CompileMode,\n fullName: FullArtifactName,\n data: CompiledTemplateV3,\n source: string,\n): TemplateWithSource {\n validateTemplateName(fullName, data);\n\n return {\n compileMode,\n fullName,\n data,\n source,\n };\n}\n\nexport type Template = {\n readonly compileMode: CompileMode;\n readonly fullName: FullArtifactName;\n readonly data: CompiledTemplateV3;\n readonly content: Uint8Array;\n};\n\nexport function newTemplateFromData(\n compileMode: CompileMode,\n fullName: FullArtifactName,\n data: CompiledTemplateV3,\n): Template {\n validateTemplateName(fullName, data);\n return {\n compileMode,\n fullName,\n data,\n content: serializeTemplate(data),\n };\n}\n\nexport function newTemplateFromContent(\n compileMode: CompileMode,\n fullName: FullArtifactName,\n content: Uint8Array,\n): Template {\n const data = parseTemplate(content);\n if (data.type !== \"pl.tengo-template.v3\") {\n throw new Error(\"malformed v3 template\");\n }\n\n validateTemplateName(fullName, data);\n return {\n compileMode,\n fullName,\n data,\n content,\n };\n}\n\nexport function templateToSource(tpl: Template): TemplateWithSource {\n return {\n compileMode: tpl.compileMode,\n fullName: tpl.fullName,\n data: tpl.data,\n source: tpl.data.hashToSource[tpl.data.template.sourceHash],\n };\n}\nfunction validateTemplateName(fullName: FullArtifactName, data: CompiledTemplateV3) {\n const nameFromData: FullArtifactNameWithoutType = parseArtefactNameAndVersion(data.template);\n\n if (\n nameFromData.pkg !== fullName.pkg ||\n nameFromData.id !== fullName.id ||\n nameFromData.version !== fullName.version\n )\n throw new Error(\n `Compiled template name don't match it's package and file names: ` +\n `${fullNameWithoutTypeToString(nameFromData)} != ${fullNameWithoutTypeToString(fullName)}`,\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"template.js","names":[],"sources":["../../src/compiler/template.ts"],"sourcesContent":["import type { CompileMode, FullArtifactName, FullArtifactNameWithoutType } from \"./package\";\nimport { fullNameWithoutTypeToString, parseArtefactNameAndVersion } from \"./package\";\nimport type { CompiledTemplateV3 } from \"@milaboratories/pl-model-backend\";\nimport { parseTemplate, serializeTemplate } from \"@milaboratories/pl-model-backend\";\n\n/** Just a holder for template data, compilation options, full name and source code.\n * It mimics ArtifactSource interface.\n */\nexport type TemplateWithSource = {\n readonly compileMode: CompileMode;\n readonly fullName: FullArtifactName;\n readonly source: string;\n readonly data: CompiledTemplateV3;\n};\n\nexport function newTemplateWithSource(\n compileMode: CompileMode,\n fullName: FullArtifactName,\n data: CompiledTemplateV3,\n source: string,\n): TemplateWithSource {\n validateTemplateName(fullName, data);\n\n return {\n compileMode,\n fullName,\n data,\n source,\n };\n}\n\nexport type Template = {\n readonly compileMode: CompileMode;\n readonly fullName: FullArtifactName;\n readonly data: CompiledTemplateV3;\n readonly content: Uint8Array;\n};\n\nexport function newTemplateFromData(\n compileMode: CompileMode,\n fullName: FullArtifactName,\n data: CompiledTemplateV3,\n): Template {\n validateTemplateName(fullName, data);\n return {\n compileMode,\n fullName,\n data,\n content: serializeTemplate(data),\n };\n}\n\nexport function newTemplateFromContent(\n compileMode: CompileMode,\n fullName: FullArtifactName,\n content: Uint8Array,\n): Template {\n const data = parseTemplate(content);\n if (data.type !== \"pl.tengo-template.v3\") {\n throw new Error(\"malformed v3 template\");\n }\n\n validateTemplateName(fullName, data);\n return {\n compileMode,\n fullName,\n data,\n content,\n };\n}\n\nexport function templateToSource(tpl: Template): TemplateWithSource {\n return {\n compileMode: tpl.compileMode,\n fullName: tpl.fullName,\n data: tpl.data,\n source: tpl.data.hashToSource[tpl.data.template.sourceHash],\n };\n}\nfunction validateTemplateName(fullName: FullArtifactName, data: CompiledTemplateV3) {\n const nameFromData: FullArtifactNameWithoutType = parseArtefactNameAndVersion(data.template);\n\n if (\n nameFromData.pkg !== fullName.pkg ||\n nameFromData.id !== fullName.id ||\n nameFromData.version !== fullName.version\n )\n throw new Error(\n `Compiled template name don't match it's package and file names: ` +\n `${fullNameWithoutTypeToString(nameFromData)} != ${fullNameWithoutTypeToString(fullName)}`,\n );\n}\n"],"mappings":";;;AAeA,SAAgB,sBACd,aACA,UACA,MACA,QACoB;AACpB,sBAAqB,UAAU,KAAK;AAEpC,QAAO;EACL;EACA;EACA;EACA;EACD;;AAwBH,SAAgB,uBACd,aACA,UACA,SACU;CACV,MAAM,OAAO,cAAc,QAAQ;AACnC,KAAI,KAAK,SAAS,uBAChB,OAAM,IAAI,MAAM,wBAAwB;AAG1C,sBAAqB,UAAU,KAAK;AACpC,QAAO;EACL;EACA;EACA;EACA;EACD;;AAGH,SAAgB,iBAAiB,KAAmC;AAClE,QAAO;EACL,aAAa,IAAI;EACjB,UAAU,IAAI;EACd,MAAM,IAAI;EACV,QAAQ,IAAI,KAAK,aAAa,IAAI,KAAK,SAAS;EACjD;;AAEH,SAAS,qBAAqB,UAA4B,MAA0B;CAClF,MAAM,eAA4C,4BAA4B,KAAK,SAAS;AAE5F,KACE,aAAa,QAAQ,SAAS,OAC9B,aAAa,OAAO,SAAS,MAC7B,aAAa,YAAY,SAAS,QAElC,OAAM,IAAI,MACR,mEACK,4BAA4B,aAAa,CAAC,MAAM,4BAA4B,SAAS,GAC3F"}
|
package/dist/compiler/util.cjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
const require_runtime = require(
|
|
1
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
2
2
|
let node_path = require("node:path");
|
|
3
3
|
node_path = require_runtime.__toESM(node_path);
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
node_fs = require_runtime.__toESM(node_fs);
|
|
6
6
|
let winston = require("winston");
|
|
7
7
|
winston = require_runtime.__toESM(winston);
|
|
8
|
-
|
|
9
8
|
//#region src/compiler/util.ts
|
|
10
9
|
function assertNever(x) {
|
|
11
10
|
throw new Error("Unexpected object: " + x);
|
|
@@ -45,10 +44,10 @@ function pathType(path) {
|
|
|
45
44
|
function isUUID(uuid) {
|
|
46
45
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(uuid.toLowerCase());
|
|
47
46
|
}
|
|
48
|
-
|
|
49
47
|
//#endregion
|
|
50
48
|
exports.assertNever = assertNever;
|
|
51
49
|
exports.createLogger = createLogger;
|
|
52
50
|
exports.isUUID = isUUID;
|
|
53
51
|
exports.pathType = pathType;
|
|
52
|
+
|
|
54
53
|
//# sourceMappingURL=util.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.cjs","names":["fs"],"sources":["../../src/compiler/util.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as winston from \"winston\";\n\nexport function assertNever(x: never): never {\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n throw new Error(\"Unexpected object: \" + x);\n}\n\nexport function createLogger(level: string = \"debug\"): winston.Logger {\n return winston.createLogger({\n level: level,\n format: winston.format.combine(\n winston.format.errors({ stack: true }),\n winston.format.printf(({ level, message, stack }) => {\n const baseMessage = `${level.padStart(6, \" \")}: ${message as string}`;\n return stack ? `${baseMessage}\\n${stack as string}` : baseMessage;\n }),\n ),\n transports: [\n new winston.transports.Console({\n stderrLevels: [\"error\", \"warn\", \"info\", \"debug\"],\n handleExceptions: true,\n }),\n ],\n });\n}\n\nexport function findNodeModules(): string {\n let currentDir = process.cwd();\n\n while (currentDir) {\n const possibleNodeModulesPath = path.join(currentDir, \"node_modules\");\n\n if (fs.existsSync(possibleNodeModulesPath)) return possibleNodeModulesPath;\n\n const parentDir = path.resolve(currentDir, \"..\");\n if (parentDir === currentDir) break; // reached the root directory\n\n currentDir = parentDir;\n }\n\n throw new Error(\"Unable to find node_modules directory.\");\n}\n\nexport type PathType = \"absent\" | \"file\" | \"dir\" | \"link\" | \"unknown\";\n\nexport function pathType(path: string): PathType {\n try {\n const s = fs.statSync(path);\n if (s.isDirectory()) return \"dir\";\n if (s.isFile()) return \"file\";\n if (s.isSymbolicLink()) return \"link\";\n return \"unknown\";\n } catch (error: unknown) {\n const err = error as NodeJS.ErrnoException;\n if (err.code == \"ENOENT\") return \"absent\";\n if (err.code == \"ENOTDIR\") return \"absent\";\n else throw err;\n }\n}\n\nexport function isUUID(uuid: string): boolean {\n const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n return uuidRegex.test(uuid.toLowerCase());\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"util.cjs","names":["fs"],"sources":["../../src/compiler/util.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as winston from \"winston\";\n\nexport function assertNever(x: never): never {\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n throw new Error(\"Unexpected object: \" + x);\n}\n\nexport function createLogger(level: string = \"debug\"): winston.Logger {\n return winston.createLogger({\n level: level,\n format: winston.format.combine(\n winston.format.errors({ stack: true }),\n winston.format.printf(({ level, message, stack }) => {\n const baseMessage = `${level.padStart(6, \" \")}: ${message as string}`;\n return stack ? `${baseMessage}\\n${stack as string}` : baseMessage;\n }),\n ),\n transports: [\n new winston.transports.Console({\n stderrLevels: [\"error\", \"warn\", \"info\", \"debug\"],\n handleExceptions: true,\n }),\n ],\n });\n}\n\nexport function findNodeModules(): string {\n let currentDir = process.cwd();\n\n while (currentDir) {\n const possibleNodeModulesPath = path.join(currentDir, \"node_modules\");\n\n if (fs.existsSync(possibleNodeModulesPath)) return possibleNodeModulesPath;\n\n const parentDir = path.resolve(currentDir, \"..\");\n if (parentDir === currentDir) break; // reached the root directory\n\n currentDir = parentDir;\n }\n\n throw new Error(\"Unable to find node_modules directory.\");\n}\n\nexport type PathType = \"absent\" | \"file\" | \"dir\" | \"link\" | \"unknown\";\n\nexport function pathType(path: string): PathType {\n try {\n const s = fs.statSync(path);\n if (s.isDirectory()) return \"dir\";\n if (s.isFile()) return \"file\";\n if (s.isSymbolicLink()) return \"link\";\n return \"unknown\";\n } catch (error: unknown) {\n const err = error as NodeJS.ErrnoException;\n if (err.code == \"ENOENT\") return \"absent\";\n if (err.code == \"ENOTDIR\") return \"absent\";\n else throw err;\n }\n}\n\nexport function isUUID(uuid: string): boolean {\n const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n return uuidRegex.test(uuid.toLowerCase());\n}\n"],"mappings":";;;;;;;;AAIA,SAAgB,YAAY,GAAiB;AAE3C,OAAM,IAAI,MAAM,wBAAwB,EAAE;;AAG5C,SAAgB,aAAa,QAAgB,SAAyB;AACpE,QAAO,QAAQ,aAAa;EACnB;EACP,QAAQ,QAAQ,OAAO,QACrB,QAAQ,OAAO,OAAO,EAAE,OAAO,MAAM,CAAC,EACtC,QAAQ,OAAO,QAAQ,EAAE,OAAO,SAAS,YAAY;GACnD,MAAM,cAAc,GAAG,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI;AAClD,UAAO,QAAQ,GAAG,YAAY,IAAI,UAAoB;IACtD,CACH;EACD,YAAY,CACV,IAAI,QAAQ,WAAW,QAAQ;GAC7B,cAAc;IAAC;IAAS;IAAQ;IAAQ;IAAQ;GAChD,kBAAkB;GACnB,CAAC,CACH;EACF,CAAC;;AAsBJ,SAAgB,SAAS,MAAwB;AAC/C,KAAI;EACF,MAAM,IAAIA,QAAG,SAAS,KAAK;AAC3B,MAAI,EAAE,aAAa,CAAE,QAAO;AAC5B,MAAI,EAAE,QAAQ,CAAE,QAAO;AACvB,MAAI,EAAE,gBAAgB,CAAE,QAAO;AAC/B,SAAO;UACA,OAAgB;EACvB,MAAM,MAAM;AACZ,MAAI,IAAI,QAAQ,SAAU,QAAO;AACjC,MAAI,IAAI,QAAQ,UAAW,QAAO;MAC7B,OAAM;;;AAIf,SAAgB,OAAO,MAAuB;AAE5C,QADkB,6EACD,KAAK,KAAK,aAAa,CAAC"}
|