@exercode/problem-utils 2.2.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/helpers/judgeByStaticAnalysis.cjs +7 -8
- package/dist/helpers/judgeByStaticAnalysis.cjs.map +1 -1
- package/dist/helpers/judgeByStaticAnalysis.js +7 -8
- package/dist/helpers/judgeByStaticAnalysis.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/types/problem.cjs +1 -1
- package/dist/types/problem.cjs.map +1 -1
- package/dist/types/problem.d.ts +26 -3
- package/dist/types/problem.js +1 -1
- package/dist/types/problem.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
"use strict";const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("./removeCommentsInSourceCode.cjs"),n=require("../types/decisionCode.cjs"),r=require("./findLanguageDefinitionByPath.cjs");let
|
|
1
|
+
"use strict";const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("./removeCommentsInSourceCode.cjs"),n=require("../types/decisionCode.cjs"),r=require("../types/problem.cjs"),i=require("./findLanguageDefinitionByPath.cjs");let a=require("node:path");a=e.__toESM(a,1);let o=require("node:fs");o=e.__toESM(o,1);async function s(e,s){let l=new Set,u=[];for(let n of await o.default.promises.readdir(e,{withFileTypes:!0,recursive:!0})){if(!n.isFile())continue;let r=a.default.relative(e,a.default.join(n.parentPath,n.name));l.add(r);let s=await o.default.promises.readFile(a.default.join(n.parentPath,n.name),`utf8`);if(s.includes(`�`))continue;let c=i.findLanguageDefinitionByPath(n.name);c&&u.push({path:r,data:c.grammer?t.removeCommentsInSourceCode(c.grammer,s):s})}if(s.requiredSubmissionFilePaths){let e=s.requiredSubmissionFilePaths.filter(e=>!l.has(e)).toSorted();if(e.length>0)return{decisionCode:n.DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,feedbackMarkdown:`ファイルが不足しています。
|
|
2
2
|
次のファイルを追加してから再度提出してください。
|
|
3
3
|
|
|
4
4
|
${e.map(e=>`- \`${e}\``).join(`
|
|
5
5
|
`)}
|
|
6
|
-
`}}let
|
|
6
|
+
`}}let d=[];for(let e of s.forbiddenRegExpsInCode??[]){let{pattern:t,message:n}=r.normalizeCodeRule(e),i=new RegExp(t,`g`),a=u.flatMap(e=>[...e.data.matchAll(i)].map(t=>({path:e.path,match:t[0]})));a.length>0&&d.push({label:n??`禁止パターン \`${i.toString()}\``,matches:a})}for(let e of s.forbiddenTextsInCode??[]){let{pattern:t,message:n}=r.normalizeCodeRule(e),i=u.filter(e=>e.data.includes(t)).map(e=>({path:e.path,match:t}));i.length>0&&d.push({label:n??`禁止文字列 \`${t}\``,matches:i})}if(d.length>0)return{decisionCode:n.DecisionCode.FORBIDDEN_PATTERNS_IN_CODE_ERROR,feedbackMarkdown:`ソースコード中に禁止された文字列が含まれています。
|
|
7
7
|
ソースコードを修正してから再度提出してください。
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
| -------- | ------------ | ------ |
|
|
11
|
-
${l.map(e=>`| \`${e.path}\` | \`${e.pattern}\` | \`${e.match}\` |`).join(`
|
|
9
|
+
${d.map(c).join(`
|
|
12
10
|
`)}
|
|
13
|
-
`};let
|
|
11
|
+
`};let f=[];for(let e of s.requiredRegExpsInCode??[]){let{pattern:t,message:n}=r.normalizeCodeRule(e),i=new RegExp(t);u.some(e=>i.test(e.data))||f.push(n??`\`${i.toString()}\``)}if(f.length>0)return{decisionCode:n.DecisionCode.REQUIRED_PATTERNS_IN_CODE_ERROR,feedbackMarkdown:`ソースコード中に必要な文字列が含まれていません。
|
|
14
12
|
ソースコードを修正してから再度提出してください。
|
|
15
13
|
|
|
16
|
-
${
|
|
14
|
+
${f.map(e=>`- ${e}`).join(`
|
|
17
15
|
`)}
|
|
18
|
-
`}}
|
|
16
|
+
`}}function c(e){let t=[...new Set(e.matches.map(({path:e,match:t})=>` - \`${e}\`: \`${t}\``))];return`- ${e.label}\n${t.join(`
|
|
17
|
+
`)}`}exports.judgeByStaticAnalysis=s;
|
|
19
18
|
//# sourceMappingURL=judgeByStaticAnalysis.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"judgeByStaticAnalysis.cjs","names":["fs","path","findLanguageDefinitionByPath","removeCommentsInSourceCode","DecisionCode"],"sources":["../../src/helpers/judgeByStaticAnalysis.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nimport { findLanguageDefinitionByPath } from './findLanguageDefinitionByPath.js';\nimport { removeCommentsInSourceCode } from './removeCommentsInSourceCode.js';\n\nexport async function judgeByStaticAnalysis(\n cwd: string,\n problemMarkdownFrontMatterLike: Pick<\n ProblemMarkdownFrontMatter,\n 'forbiddenRegExpsInCode' | 'forbiddenTextsInCode' | 'requiredRegExpsInCode' | 'requiredSubmissionFilePaths'\n >\n): Promise<Pick<TestCaseResult, 'decisionCode' | 'feedbackMarkdown'> | undefined> {\n const filePathSet = new Set<string>();\n const sourceCodeWithoutCommentFiles: { path: string; data: string }[] = [];\n\n for (const dirent of await fs.promises.readdir(cwd, { withFileTypes: true, recursive: true })) {\n if (!dirent.isFile()) continue;\n\n const relativePath = path.relative(cwd, path.join(dirent.parentPath, dirent.name));\n filePathSet.add(relativePath);\n\n const text = await fs.promises.readFile(path.join(dirent.parentPath, dirent.name), 'utf8');\n const isBinary = text.includes('\\uFFFD');\n if (isBinary) continue;\n\n const languageDefinition = findLanguageDefinitionByPath(dirent.name);\n if (!languageDefinition) continue;\n\n sourceCodeWithoutCommentFiles.push({\n path:
|
|
1
|
+
{"version":3,"file":"judgeByStaticAnalysis.cjs","names":["fs","path","findLanguageDefinitionByPath","removeCommentsInSourceCode","DecisionCode","normalizeCodeRule"],"sources":["../../src/helpers/judgeByStaticAnalysis.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport { normalizeCodeRule } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nimport { findLanguageDefinitionByPath } from './findLanguageDefinitionByPath.js';\nimport { removeCommentsInSourceCode } from './removeCommentsInSourceCode.js';\n\ninterface ForbiddenRuleViolation {\n /** Learner-facing description of the rule; the raw pattern when the problem declares no message. */\n label: string;\n matches: { path: string; match: string }[];\n}\n\nexport async function judgeByStaticAnalysis(\n cwd: string,\n problemMarkdownFrontMatterLike: Pick<\n ProblemMarkdownFrontMatter,\n 'forbiddenRegExpsInCode' | 'forbiddenTextsInCode' | 'requiredRegExpsInCode' | 'requiredSubmissionFilePaths'\n >\n): Promise<Pick<TestCaseResult, 'decisionCode' | 'feedbackMarkdown'> | undefined> {\n const filePathSet = new Set<string>();\n const sourceCodeWithoutCommentFiles: { path: string; data: string }[] = [];\n\n for (const dirent of await fs.promises.readdir(cwd, { withFileTypes: true, recursive: true })) {\n if (!dirent.isFile()) continue;\n\n const relativePath = path.relative(cwd, path.join(dirent.parentPath, dirent.name));\n filePathSet.add(relativePath);\n\n const text = await fs.promises.readFile(path.join(dirent.parentPath, dirent.name), 'utf8');\n const isBinary = text.includes('\\uFFFD');\n if (isBinary) continue;\n\n const languageDefinition = findLanguageDefinitionByPath(dirent.name);\n if (!languageDefinition) continue;\n\n sourceCodeWithoutCommentFiles.push({\n path: relativePath,\n data: languageDefinition.grammer ? removeCommentsInSourceCode(languageDefinition.grammer, text) : text,\n });\n }\n\n if (problemMarkdownFrontMatterLike.requiredSubmissionFilePaths) {\n const missingFilePaths = problemMarkdownFrontMatterLike.requiredSubmissionFilePaths\n .filter((p) => !filePathSet.has(p))\n .toSorted();\n\n if (missingFilePaths.length > 0) {\n return {\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n feedbackMarkdown: `ファイルが不足しています。\n次のファイルを追加してから再度提出してください。\n\n${missingFilePaths.map((p) => `- \\`${p}\\``).join('\\n')}\n`,\n };\n }\n }\n\n const violations: ForbiddenRuleViolation[] = [];\n\n for (const rule of problemMarkdownFrontMatterLike.forbiddenRegExpsInCode ?? []) {\n const { pattern, message } = normalizeCodeRule(rule);\n const re = new RegExp(pattern, 'g');\n const matches = sourceCodeWithoutCommentFiles.flatMap((file) =>\n [...file.data.matchAll(re)].map((match) => ({ path: file.path, match: match[0] }))\n );\n if (matches.length > 0) violations.push({ label: message ?? `禁止パターン \\`${re.toString()}\\``, matches });\n }\n for (const rule of problemMarkdownFrontMatterLike.forbiddenTextsInCode ?? []) {\n const { pattern, message } = normalizeCodeRule(rule);\n const matches = sourceCodeWithoutCommentFiles\n .filter((file) => file.data.includes(pattern))\n .map((file) => ({ path: file.path, match: pattern }));\n if (matches.length > 0) violations.push({ label: message ?? `禁止文字列 \\`${pattern}\\``, matches });\n }\n\n if (violations.length > 0) {\n return {\n decisionCode: DecisionCode.FORBIDDEN_PATTERNS_IN_CODE_ERROR,\n feedbackMarkdown: `ソースコード中に禁止された文字列が含まれています。\nソースコードを修正してから再度提出してください。\n\n${violations.map(formatForbiddenRuleViolation).join('\\n')}\n`,\n };\n }\n\n const missingRequiredLabels: string[] = [];\n\n for (const rule of problemMarkdownFrontMatterLike.requiredRegExpsInCode ?? []) {\n const { pattern, message } = normalizeCodeRule(rule);\n const re = new RegExp(pattern);\n const isFound = sourceCodeWithoutCommentFiles.some((f) => re.test(f.data));\n if (!isFound) missingRequiredLabels.push(message ?? `\\`${re.toString()}\\``);\n }\n\n if (missingRequiredLabels.length > 0) {\n return {\n decisionCode: DecisionCode.REQUIRED_PATTERNS_IN_CODE_ERROR,\n feedbackMarkdown: `ソースコード中に必要な文字列が含まれていません。\nソースコードを修正してから再度提出してください。\n\n${missingRequiredLabels.map((label) => `- ${label}`).join('\\n')}\n`,\n };\n }\n\n return;\n}\n\nfunction formatForbiddenRuleViolation(violation: ForbiddenRuleViolation): string {\n const locations = [...new Set(violation.matches.map(({ path, match }) => ` - \\`${path}\\`: \\`${match}\\``))];\n return `- ${violation.label}\\n${locations.join('\\n')}`;\n}\n"],"mappings":"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"}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import{removeCommentsInSourceCode as e}from"./removeCommentsInSourceCode.js";import{DecisionCode as t}from"../types/decisionCode.js";import{
|
|
1
|
+
import{removeCommentsInSourceCode as e}from"./removeCommentsInSourceCode.js";import{DecisionCode as t}from"../types/decisionCode.js";import{normalizeCodeRule as n}from"../types/problem.js";import{findLanguageDefinitionByPath as r}from"./findLanguageDefinitionByPath.js";import i from"node:path";import a from"node:fs";async function o(o,c){let l=new Set,u=[];for(let t of await a.promises.readdir(o,{withFileTypes:!0,recursive:!0})){if(!t.isFile())continue;let n=i.relative(o,i.join(t.parentPath,t.name));l.add(n);let s=await a.promises.readFile(i.join(t.parentPath,t.name),`utf8`);if(s.includes(`�`))continue;let c=r(t.name);c&&u.push({path:n,data:c.grammer?e(c.grammer,s):s})}if(c.requiredSubmissionFilePaths){let e=c.requiredSubmissionFilePaths.filter(e=>!l.has(e)).toSorted();if(e.length>0)return{decisionCode:t.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,feedbackMarkdown:`ファイルが不足しています。
|
|
2
2
|
次のファイルを追加してから再度提出してください。
|
|
3
3
|
|
|
4
4
|
${e.map(e=>`- \`${e}\``).join(`
|
|
5
5
|
`)}
|
|
6
|
-
`}}let
|
|
6
|
+
`}}let d=[];for(let e of c.forbiddenRegExpsInCode??[]){let{pattern:t,message:r}=n(e),i=new RegExp(t,`g`),a=u.flatMap(e=>[...e.data.matchAll(i)].map(t=>({path:e.path,match:t[0]})));a.length>0&&d.push({label:r??`禁止パターン \`${i.toString()}\``,matches:a})}for(let e of c.forbiddenTextsInCode??[]){let{pattern:t,message:r}=n(e),i=u.filter(e=>e.data.includes(t)).map(e=>({path:e.path,match:t}));i.length>0&&d.push({label:r??`禁止文字列 \`${t}\``,matches:i})}if(d.length>0)return{decisionCode:t.FORBIDDEN_PATTERNS_IN_CODE_ERROR,feedbackMarkdown:`ソースコード中に禁止された文字列が含まれています。
|
|
7
7
|
ソースコードを修正してから再度提出してください。
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
| -------- | ------------ | ------ |
|
|
11
|
-
${l.map(e=>`| \`${e.path}\` | \`${e.pattern}\` | \`${e.match}\` |`).join(`
|
|
9
|
+
${d.map(s).join(`
|
|
12
10
|
`)}
|
|
13
|
-
`};let
|
|
11
|
+
`};let f=[];for(let e of c.requiredRegExpsInCode??[]){let{pattern:t,message:r}=n(e),i=new RegExp(t);u.some(e=>i.test(e.data))||f.push(r??`\`${i.toString()}\``)}if(f.length>0)return{decisionCode:t.REQUIRED_PATTERNS_IN_CODE_ERROR,feedbackMarkdown:`ソースコード中に必要な文字列が含まれていません。
|
|
14
12
|
ソースコードを修正してから再度提出してください。
|
|
15
13
|
|
|
16
|
-
${
|
|
14
|
+
${f.map(e=>`- ${e}`).join(`
|
|
17
15
|
`)}
|
|
18
|
-
`}}
|
|
16
|
+
`}}function s(e){let t=[...new Set(e.matches.map(({path:e,match:t})=>` - \`${e}\`: \`${t}\``))];return`- ${e.label}\n${t.join(`
|
|
17
|
+
`)}`}export{o as judgeByStaticAnalysis};
|
|
19
18
|
//# sourceMappingURL=judgeByStaticAnalysis.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"judgeByStaticAnalysis.js","names":[],"sources":["../../src/helpers/judgeByStaticAnalysis.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nimport { findLanguageDefinitionByPath } from './findLanguageDefinitionByPath.js';\nimport { removeCommentsInSourceCode } from './removeCommentsInSourceCode.js';\n\nexport async function judgeByStaticAnalysis(\n cwd: string,\n problemMarkdownFrontMatterLike: Pick<\n ProblemMarkdownFrontMatter,\n 'forbiddenRegExpsInCode' | 'forbiddenTextsInCode' | 'requiredRegExpsInCode' | 'requiredSubmissionFilePaths'\n >\n): Promise<Pick<TestCaseResult, 'decisionCode' | 'feedbackMarkdown'> | undefined> {\n const filePathSet = new Set<string>();\n const sourceCodeWithoutCommentFiles: { path: string; data: string }[] = [];\n\n for (const dirent of await fs.promises.readdir(cwd, { withFileTypes: true, recursive: true })) {\n if (!dirent.isFile()) continue;\n\n const relativePath = path.relative(cwd, path.join(dirent.parentPath, dirent.name));\n filePathSet.add(relativePath);\n\n const text = await fs.promises.readFile(path.join(dirent.parentPath, dirent.name), 'utf8');\n const isBinary = text.includes('\\uFFFD');\n if (isBinary) continue;\n\n const languageDefinition = findLanguageDefinitionByPath(dirent.name);\n if (!languageDefinition) continue;\n\n sourceCodeWithoutCommentFiles.push({\n path:
|
|
1
|
+
{"version":3,"file":"judgeByStaticAnalysis.js","names":[],"sources":["../../src/helpers/judgeByStaticAnalysis.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport { normalizeCodeRule } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nimport { findLanguageDefinitionByPath } from './findLanguageDefinitionByPath.js';\nimport { removeCommentsInSourceCode } from './removeCommentsInSourceCode.js';\n\ninterface ForbiddenRuleViolation {\n /** Learner-facing description of the rule; the raw pattern when the problem declares no message. */\n label: string;\n matches: { path: string; match: string }[];\n}\n\nexport async function judgeByStaticAnalysis(\n cwd: string,\n problemMarkdownFrontMatterLike: Pick<\n ProblemMarkdownFrontMatter,\n 'forbiddenRegExpsInCode' | 'forbiddenTextsInCode' | 'requiredRegExpsInCode' | 'requiredSubmissionFilePaths'\n >\n): Promise<Pick<TestCaseResult, 'decisionCode' | 'feedbackMarkdown'> | undefined> {\n const filePathSet = new Set<string>();\n const sourceCodeWithoutCommentFiles: { path: string; data: string }[] = [];\n\n for (const dirent of await fs.promises.readdir(cwd, { withFileTypes: true, recursive: true })) {\n if (!dirent.isFile()) continue;\n\n const relativePath = path.relative(cwd, path.join(dirent.parentPath, dirent.name));\n filePathSet.add(relativePath);\n\n const text = await fs.promises.readFile(path.join(dirent.parentPath, dirent.name), 'utf8');\n const isBinary = text.includes('\\uFFFD');\n if (isBinary) continue;\n\n const languageDefinition = findLanguageDefinitionByPath(dirent.name);\n if (!languageDefinition) continue;\n\n sourceCodeWithoutCommentFiles.push({\n path: relativePath,\n data: languageDefinition.grammer ? removeCommentsInSourceCode(languageDefinition.grammer, text) : text,\n });\n }\n\n if (problemMarkdownFrontMatterLike.requiredSubmissionFilePaths) {\n const missingFilePaths = problemMarkdownFrontMatterLike.requiredSubmissionFilePaths\n .filter((p) => !filePathSet.has(p))\n .toSorted();\n\n if (missingFilePaths.length > 0) {\n return {\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n feedbackMarkdown: `ファイルが不足しています。\n次のファイルを追加してから再度提出してください。\n\n${missingFilePaths.map((p) => `- \\`${p}\\``).join('\\n')}\n`,\n };\n }\n }\n\n const violations: ForbiddenRuleViolation[] = [];\n\n for (const rule of problemMarkdownFrontMatterLike.forbiddenRegExpsInCode ?? []) {\n const { pattern, message } = normalizeCodeRule(rule);\n const re = new RegExp(pattern, 'g');\n const matches = sourceCodeWithoutCommentFiles.flatMap((file) =>\n [...file.data.matchAll(re)].map((match) => ({ path: file.path, match: match[0] }))\n );\n if (matches.length > 0) violations.push({ label: message ?? `禁止パターン \\`${re.toString()}\\``, matches });\n }\n for (const rule of problemMarkdownFrontMatterLike.forbiddenTextsInCode ?? []) {\n const { pattern, message } = normalizeCodeRule(rule);\n const matches = sourceCodeWithoutCommentFiles\n .filter((file) => file.data.includes(pattern))\n .map((file) => ({ path: file.path, match: pattern }));\n if (matches.length > 0) violations.push({ label: message ?? `禁止文字列 \\`${pattern}\\``, matches });\n }\n\n if (violations.length > 0) {\n return {\n decisionCode: DecisionCode.FORBIDDEN_PATTERNS_IN_CODE_ERROR,\n feedbackMarkdown: `ソースコード中に禁止された文字列が含まれています。\nソースコードを修正してから再度提出してください。\n\n${violations.map(formatForbiddenRuleViolation).join('\\n')}\n`,\n };\n }\n\n const missingRequiredLabels: string[] = [];\n\n for (const rule of problemMarkdownFrontMatterLike.requiredRegExpsInCode ?? []) {\n const { pattern, message } = normalizeCodeRule(rule);\n const re = new RegExp(pattern);\n const isFound = sourceCodeWithoutCommentFiles.some((f) => re.test(f.data));\n if (!isFound) missingRequiredLabels.push(message ?? `\\`${re.toString()}\\``);\n }\n\n if (missingRequiredLabels.length > 0) {\n return {\n decisionCode: DecisionCode.REQUIRED_PATTERNS_IN_CODE_ERROR,\n feedbackMarkdown: `ソースコード中に必要な文字列が含まれていません。\nソースコードを修正してから再度提出してください。\n\n${missingRequiredLabels.map((label) => `- ${label}`).join('\\n')}\n`,\n };\n }\n\n return;\n}\n\nfunction formatForbiddenRuleViolation(violation: ForbiddenRuleViolation): string {\n const locations = [...new Set(violation.matches.map(({ path, match }) => ` - \\`${path}\\`: \\`${match}\\``))];\n return `- ${violation.label}\\n${locations.join('\\n')}`;\n}\n"],"mappings":"8TAiBA,eAAsB,EACpB,EACA,EAIgF,CAChF,IAAM,EAAc,IAAI,IAClB,EAAkE,CAAC,EAEzE,IAAK,IAAM,KAAU,MAAM,EAAG,SAAS,QAAQ,EAAK,CAAE,cAAe,GAAM,UAAW,EAAK,CAAC,EAAG,CAC7F,GAAI,CAAC,EAAO,OAAO,EAAG,SAEtB,IAAM,EAAe,EAAK,SAAS,EAAK,EAAK,KAAK,EAAO,WAAY,EAAO,IAAI,CAAC,EACjF,EAAY,IAAI,CAAY,EAE5B,IAAM,EAAO,MAAM,EAAG,SAAS,SAAS,EAAK,KAAK,EAAO,WAAY,EAAO,IAAI,EAAG,MAAM,EAEzF,GADiB,EAAK,SAAS,GACpB,EAAG,SAEd,IAAM,EAAqB,EAA6B,EAAO,IAAI,EAC9D,GAEL,EAA8B,KAAK,CACjC,KAAM,EACN,KAAM,EAAmB,QAAU,EAA2B,EAAmB,QAAS,CAAI,EAAI,CACpG,CAAC,CACH,CAEA,GAAI,EAA+B,4BAA6B,CAC9D,IAAM,EAAmB,EAA+B,4BACrD,OAAQ,GAAM,CAAC,EAAY,IAAI,CAAC,CAAC,CAAC,CAClC,SAAS,EAEZ,GAAI,EAAiB,OAAS,EAC5B,MAAO,CACL,aAAc,EAAa,uCAC3B,iBAAkB;;;EAGxB,EAAiB,IAAK,GAAM,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK;CAAI,EAAE;CAEjD,CAEJ,CAEA,IAAM,EAAuC,CAAC,EAE9C,IAAK,IAAM,KAAQ,EAA+B,wBAA0B,CAAC,EAAG,CAC9E,GAAM,CAAE,UAAS,WAAY,EAAkB,CAAI,EAC7C,EAAK,IAAI,OAAO,EAAS,GAAG,EAC5B,EAAU,EAA8B,QAAS,GACrD,CAAC,GAAG,EAAK,KAAK,SAAS,CAAE,CAAC,CAAC,CAAC,IAAK,IAAW,CAAE,KAAM,EAAK,KAAM,MAAO,EAAM,EAAG,EAAE,CACnF,EACI,EAAQ,OAAS,GAAG,EAAW,KAAK,CAAE,MAAO,GAAW,YAAY,EAAG,SAAS,EAAE,IAAK,SAAQ,CAAC,CACtG,CACA,IAAK,IAAM,KAAQ,EAA+B,sBAAwB,CAAC,EAAG,CAC5E,GAAM,CAAE,UAAS,WAAY,EAAkB,CAAI,EAC7C,EAAU,EACb,OAAQ,GAAS,EAAK,KAAK,SAAS,CAAO,CAAC,CAAC,CAC7C,IAAK,IAAU,CAAE,KAAM,EAAK,KAAM,MAAO,CAAQ,EAAE,EAClD,EAAQ,OAAS,GAAG,EAAW,KAAK,CAAE,MAAO,GAAW,WAAW,EAAQ,IAAK,SAAQ,CAAC,CAC/F,CAEA,GAAI,EAAW,OAAS,EACtB,MAAO,CACL,aAAc,EAAa,iCAC3B,iBAAkB;;;EAGtB,EAAW,IAAI,CAA4B,CAAC,CAAC,KAAK;CAAI,EAAE;CAEtD,EAGF,IAAM,EAAkC,CAAC,EAEzC,IAAK,IAAM,KAAQ,EAA+B,uBAAyB,CAAC,EAAG,CAC7E,GAAM,CAAE,UAAS,WAAY,EAAkB,CAAI,EAC7C,EAAK,IAAI,OAAO,CAAO,EACb,EAA8B,KAAM,GAAM,EAAG,KAAK,EAAE,IAAI,CAC7D,GAAG,EAAsB,KAAK,GAAW,KAAK,EAAG,SAAS,EAAE,GAAG,CAC5E,CAEA,GAAI,EAAsB,OAAS,EACjC,MAAO,CACL,aAAc,EAAa,gCAC3B,iBAAkB;;;EAGtB,EAAsB,IAAK,GAAU,KAAK,GAAO,CAAC,CAAC,KAAK;CAAI,EAAE;CAE5D,CAIJ,CAEA,SAAS,EAA6B,EAA2C,CAC/E,IAAM,EAAY,CAAC,GAAG,IAAI,IAAI,EAAU,QAAQ,KAAK,CAAE,OAAM,WAAY,SAAS,EAAK,QAAQ,EAAM,GAAG,CAAC,CAAC,EAC1G,MAAO,KAAK,EAAU,MAAM,IAAI,EAAU,KAAK;CAAI,GACrD"}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./helpers/defaultStdioHarness.cjs"),t=require("./helpers/parseArgs.cjs"),n=require("./helpers/parseCsv.cjs"),r=require("./types/testCaseResult.cjs"),i=require("./helpers/printTestCaseResult.cjs"),a=require("./helpers/removeCommentsInSourceCode.cjs"),o=require("./helpers/sandboxUser.cjs"),s=require("./helpers/safeFs.cjs"),c=require("./helpers/runCommandInTemporaryPackageManagerProject.cjs"),l=require("./helpers/runPythonInTemporaryUvProject.cjs"),u=require("./helpers/sourceCodeGrammars.cjs"),d=require("./helpers/startHttpServer.cjs"),f=require("./types/decisionCode.cjs");exports.CsvParseError=n.CsvParseError,exports.DecisionCode=f.DecisionCode,exports.HARNESS_FILE_PRESETS=e.HARNESS_FILE_PRESETS,exports.SANDBOX_ENV_PREFIX=o.SANDBOX_ENV_PREFIX,exports.SANDBOX_USER_ENV_NAME=o.SANDBOX_USER_ENV_NAME,exports.SANDBOX_WATCHDOG_GRACE_SECONDS=o.SANDBOX_WATCHDOG_GRACE_SECONDS,exports.TEST_CASE_RESULT_PREFIX=r.TEST_CASE_RESULT_PREFIX,exports.TIMEOUT_COMMAND=o.TIMEOUT_COMMAND,exports.copyPackageManagerProjectFiles=c.copyPackageManagerProjectFiles,exports.copyWithoutFollowingSymlinks=s.copyWithoutFollowingSymlinks,exports.createDirectoryWithoutFollowingSymlinks=s.createDirectoryWithoutFollowingSymlinks,exports.encodeFileForTestCaseResult=i.encodeFileForTestCaseResult,exports.findDefaultStdioHarnessFiles=e.findDefaultStdioHarnessFiles,exports.forceRemove=o.forceRemove,exports.getSandboxUserEnvOverrides=o.getSandboxUserEnvOverrides,exports.getTrustedHelperEnv=o.getTrustedHelperEnv,exports.isContainedPath=s.isContainedPath,exports.isDefaultStdioHarnessSource=e.isDefaultStdioHarnessSource,exports.isSandboxWrappedCommand=o.isSandboxWrappedCommand,exports.killSandboxUserProcesses=o.killSandboxUserProcesses,exports.languageIdToSourceCodeGrammar=u.languageIdToSourceCodeGrammar,exports.makeAccessibleToSandboxUser=o.makeAccessibleToSandboxUser,exports.parseArgs=t.parseArgs,exports.parseCsv=n.parseCsv,exports.parseCsvRecords=n.parseCsvRecords,exports.prependInsideSandboxWrapper=o.prependInsideSandboxWrapper,exports.printTestCaseResult=i.printTestCaseResult,exports.relaxPermissionsAsSandboxUser=o.relaxPermissionsAsSandboxUser,exports.removeCommentsAndStringsInSourceCode=a.removeCommentsAndStringsInSourceCode,exports.removeCommentsInSourceCode=a.removeCommentsInSourceCode,exports.runCommandInTemporaryPackageManagerProject=c.runCommandInTemporaryPackageManagerProject,exports.runPythonInTemporaryUvProject=l.runPythonInTemporaryUvProject,exports.sandboxUserName=o.sandboxUserName,exports.startHttpServer=d.startHttpServer,exports.startSandboxTimeoutWatchdog=o.startSandboxTimeoutWatchdog,exports.testCaseResultSchema=r.testCaseResultSchema,exports.wrapCommandWithSandboxUser=o.wrapCommandWithSandboxUser,exports.writeFileWithoutFollowingSymlinks=s.writeFileWithoutFollowingSymlinks;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./helpers/defaultStdioHarness.cjs"),t=require("./helpers/parseArgs.cjs"),n=require("./helpers/parseCsv.cjs"),r=require("./types/testCaseResult.cjs"),i=require("./helpers/printTestCaseResult.cjs"),a=require("./helpers/removeCommentsInSourceCode.cjs"),o=require("./helpers/sandboxUser.cjs"),s=require("./helpers/safeFs.cjs"),c=require("./helpers/runCommandInTemporaryPackageManagerProject.cjs"),l=require("./helpers/runPythonInTemporaryUvProject.cjs"),u=require("./helpers/sourceCodeGrammars.cjs"),d=require("./helpers/startHttpServer.cjs"),f=require("./types/decisionCode.cjs"),p=require("./types/problem.cjs");exports.CsvParseError=n.CsvParseError,exports.DecisionCode=f.DecisionCode,exports.HARNESS_FILE_PRESETS=e.HARNESS_FILE_PRESETS,exports.SANDBOX_ENV_PREFIX=o.SANDBOX_ENV_PREFIX,exports.SANDBOX_USER_ENV_NAME=o.SANDBOX_USER_ENV_NAME,exports.SANDBOX_WATCHDOG_GRACE_SECONDS=o.SANDBOX_WATCHDOG_GRACE_SECONDS,exports.TEST_CASE_RESULT_PREFIX=r.TEST_CASE_RESULT_PREFIX,exports.TIMEOUT_COMMAND=o.TIMEOUT_COMMAND,exports.codeRuleSchema=p.codeRuleSchema,exports.copyPackageManagerProjectFiles=c.copyPackageManagerProjectFiles,exports.copyWithoutFollowingSymlinks=s.copyWithoutFollowingSymlinks,exports.createDirectoryWithoutFollowingSymlinks=s.createDirectoryWithoutFollowingSymlinks,exports.encodeFileForTestCaseResult=i.encodeFileForTestCaseResult,exports.findDefaultStdioHarnessFiles=e.findDefaultStdioHarnessFiles,exports.forceRemove=o.forceRemove,exports.getSandboxUserEnvOverrides=o.getSandboxUserEnvOverrides,exports.getTrustedHelperEnv=o.getTrustedHelperEnv,exports.isContainedPath=s.isContainedPath,exports.isDefaultStdioHarnessSource=e.isDefaultStdioHarnessSource,exports.isSandboxWrappedCommand=o.isSandboxWrappedCommand,exports.killSandboxUserProcesses=o.killSandboxUserProcesses,exports.languageIdToSourceCodeGrammar=u.languageIdToSourceCodeGrammar,exports.makeAccessibleToSandboxUser=o.makeAccessibleToSandboxUser,exports.normalizeCodeRule=p.normalizeCodeRule,exports.parseArgs=t.parseArgs,exports.parseCsv=n.parseCsv,exports.parseCsvRecords=n.parseCsvRecords,exports.prependInsideSandboxWrapper=o.prependInsideSandboxWrapper,exports.printTestCaseResult=i.printTestCaseResult,exports.problemMarkdownFrontMatterSchema=p.problemMarkdownFrontMatterSchema,exports.relaxPermissionsAsSandboxUser=o.relaxPermissionsAsSandboxUser,exports.removeCommentsAndStringsInSourceCode=a.removeCommentsAndStringsInSourceCode,exports.removeCommentsInSourceCode=a.removeCommentsInSourceCode,exports.runCommandInTemporaryPackageManagerProject=c.runCommandInTemporaryPackageManagerProject,exports.runPythonInTemporaryUvProject=l.runPythonInTemporaryUvProject,exports.sandboxUserName=o.sandboxUserName,exports.startHttpServer=d.startHttpServer,exports.startSandboxTimeoutWatchdog=o.startSandboxTimeoutWatchdog,exports.testCaseResultSchema=r.testCaseResultSchema,exports.wrapCommandWithSandboxUser=o.wrapCommandWithSandboxUser,exports.writeFileWithoutFollowingSymlinks=s.writeFileWithoutFollowingSymlinks;
|
package/dist/index.d.ts
CHANGED
|
@@ -10,4 +10,5 @@ export * from './helpers/sandboxUser.js';
|
|
|
10
10
|
export * from './helpers/sourceCodeGrammars.js';
|
|
11
11
|
export * from './helpers/startHttpServer.js';
|
|
12
12
|
export * from './types/decisionCode.js';
|
|
13
|
+
export * from './types/problem.js';
|
|
13
14
|
export * from './types/testCaseResult.js';
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{HARNESS_FILE_PRESETS as e,findDefaultStdioHarnessFiles as t,isDefaultStdioHarnessSource as n}from"./helpers/defaultStdioHarness.js";import{parseArgs as r}from"./helpers/parseArgs.js";import{CsvParseError as i,parseCsv as a,parseCsvRecords as o}from"./helpers/parseCsv.js";import{TEST_CASE_RESULT_PREFIX as s,testCaseResultSchema as c}from"./types/testCaseResult.js";import{encodeFileForTestCaseResult as l,printTestCaseResult as u}from"./helpers/printTestCaseResult.js";import{removeCommentsAndStringsInSourceCode as d,removeCommentsInSourceCode as f}from"./helpers/removeCommentsInSourceCode.js";import{SANDBOX_ENV_PREFIX as p,SANDBOX_USER_ENV_NAME as m,SANDBOX_WATCHDOG_GRACE_SECONDS as h,TIMEOUT_COMMAND as g,forceRemove as _,getSandboxUserEnvOverrides as v,getTrustedHelperEnv as y,isSandboxWrappedCommand as b,killSandboxUserProcesses as x,makeAccessibleToSandboxUser as S,prependInsideSandboxWrapper as C,relaxPermissionsAsSandboxUser as w,sandboxUserName as T,startSandboxTimeoutWatchdog as E,wrapCommandWithSandboxUser as D}from"./helpers/sandboxUser.js";import{copyWithoutFollowingSymlinks as O,createDirectoryWithoutFollowingSymlinks as k,isContainedPath as A,writeFileWithoutFollowingSymlinks as j}from"./helpers/safeFs.js";import{copyPackageManagerProjectFiles as M,runCommandInTemporaryPackageManagerProject as N}from"./helpers/runCommandInTemporaryPackageManagerProject.js";import{runPythonInTemporaryUvProject as P}from"./helpers/runPythonInTemporaryUvProject.js";import{languageIdToSourceCodeGrammar as F}from"./helpers/sourceCodeGrammars.js";import{startHttpServer as I}from"./helpers/startHttpServer.js";import{DecisionCode as L}from"./types/decisionCode.js";export{i as CsvParseError,L as DecisionCode,e as HARNESS_FILE_PRESETS,p as SANDBOX_ENV_PREFIX,m as SANDBOX_USER_ENV_NAME,h as SANDBOX_WATCHDOG_GRACE_SECONDS,s as TEST_CASE_RESULT_PREFIX,g as TIMEOUT_COMMAND,M as copyPackageManagerProjectFiles,O as copyWithoutFollowingSymlinks,k as createDirectoryWithoutFollowingSymlinks,l as encodeFileForTestCaseResult,t as findDefaultStdioHarnessFiles,_ as forceRemove,v as getSandboxUserEnvOverrides,y as getTrustedHelperEnv,A as isContainedPath,n as isDefaultStdioHarnessSource,b as isSandboxWrappedCommand,x as killSandboxUserProcesses,F as languageIdToSourceCodeGrammar,S as makeAccessibleToSandboxUser,r as parseArgs,a as parseCsv,o as parseCsvRecords,C as prependInsideSandboxWrapper,u as printTestCaseResult,w as relaxPermissionsAsSandboxUser,d as removeCommentsAndStringsInSourceCode,f as removeCommentsInSourceCode,N as runCommandInTemporaryPackageManagerProject,P as runPythonInTemporaryUvProject,T as sandboxUserName,I as startHttpServer,E as startSandboxTimeoutWatchdog,c as testCaseResultSchema,D as wrapCommandWithSandboxUser,j as writeFileWithoutFollowingSymlinks};
|
|
1
|
+
import{HARNESS_FILE_PRESETS as e,findDefaultStdioHarnessFiles as t,isDefaultStdioHarnessSource as n}from"./helpers/defaultStdioHarness.js";import{parseArgs as r}from"./helpers/parseArgs.js";import{CsvParseError as i,parseCsv as a,parseCsvRecords as o}from"./helpers/parseCsv.js";import{TEST_CASE_RESULT_PREFIX as s,testCaseResultSchema as c}from"./types/testCaseResult.js";import{encodeFileForTestCaseResult as l,printTestCaseResult as u}from"./helpers/printTestCaseResult.js";import{removeCommentsAndStringsInSourceCode as d,removeCommentsInSourceCode as f}from"./helpers/removeCommentsInSourceCode.js";import{SANDBOX_ENV_PREFIX as p,SANDBOX_USER_ENV_NAME as m,SANDBOX_WATCHDOG_GRACE_SECONDS as h,TIMEOUT_COMMAND as g,forceRemove as _,getSandboxUserEnvOverrides as v,getTrustedHelperEnv as y,isSandboxWrappedCommand as b,killSandboxUserProcesses as x,makeAccessibleToSandboxUser as S,prependInsideSandboxWrapper as C,relaxPermissionsAsSandboxUser as w,sandboxUserName as T,startSandboxTimeoutWatchdog as E,wrapCommandWithSandboxUser as D}from"./helpers/sandboxUser.js";import{copyWithoutFollowingSymlinks as O,createDirectoryWithoutFollowingSymlinks as k,isContainedPath as A,writeFileWithoutFollowingSymlinks as j}from"./helpers/safeFs.js";import{copyPackageManagerProjectFiles as M,runCommandInTemporaryPackageManagerProject as N}from"./helpers/runCommandInTemporaryPackageManagerProject.js";import{runPythonInTemporaryUvProject as P}from"./helpers/runPythonInTemporaryUvProject.js";import{languageIdToSourceCodeGrammar as F}from"./helpers/sourceCodeGrammars.js";import{startHttpServer as I}from"./helpers/startHttpServer.js";import{DecisionCode as L}from"./types/decisionCode.js";import{codeRuleSchema as R,normalizeCodeRule as z,problemMarkdownFrontMatterSchema as B}from"./types/problem.js";export{i as CsvParseError,L as DecisionCode,e as HARNESS_FILE_PRESETS,p as SANDBOX_ENV_PREFIX,m as SANDBOX_USER_ENV_NAME,h as SANDBOX_WATCHDOG_GRACE_SECONDS,s as TEST_CASE_RESULT_PREFIX,g as TIMEOUT_COMMAND,R as codeRuleSchema,M as copyPackageManagerProjectFiles,O as copyWithoutFollowingSymlinks,k as createDirectoryWithoutFollowingSymlinks,l as encodeFileForTestCaseResult,t as findDefaultStdioHarnessFiles,_ as forceRemove,v as getSandboxUserEnvOverrides,y as getTrustedHelperEnv,A as isContainedPath,n as isDefaultStdioHarnessSource,b as isSandboxWrappedCommand,x as killSandboxUserProcesses,F as languageIdToSourceCodeGrammar,S as makeAccessibleToSandboxUser,z as normalizeCodeRule,r as parseArgs,a as parseCsv,o as parseCsvRecords,C as prependInsideSandboxWrapper,u as printTestCaseResult,B as problemMarkdownFrontMatterSchema,w as relaxPermissionsAsSandboxUser,d as removeCommentsAndStringsInSourceCode,f as removeCommentsInSourceCode,N as runCommandInTemporaryPackageManagerProject,P as runPythonInTemporaryUvProject,T as sandboxUserName,I as startHttpServer,E as startSandboxTimeoutWatchdog,c as testCaseResultSchema,D as wrapCommandWithSandboxUser,j as writeFileWithoutFollowingSymlinks};
|
package/dist/types/problem.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";let e=require("zod");const t=e.z.object({
|
|
1
|
+
"use strict";let e=require("zod");const t=e.z.union([e.z.string().min(1),e.z.object({pattern:e.z.string().min(1),message:e.z.string().min(1).refine(e=>!/[\r\n]/.test(e),`message must be a single line`)})]),n=e.z.object({timeLimitMs:e.z.number().int().min(0).optional(),memoryLimitByte:e.z.number().int().min(0).optional(),requiredRegExpsInCode:e.z.array(t).optional(),forbiddenRegExpsInCode:e.z.array(t).optional(),forbiddenTextsInCode:e.z.array(t).optional(),isManualScoringRequired:e.z.boolean().optional(),requiredEnvironmentVariables:e.z.array(e.z.string().min(1)).optional(),requiredOutputFilePaths:e.z.array(e.z.string().min(1)).optional(),requiredSubmissionFilePaths:e.z.array(e.z.string().min(1)).optional()});function r(e){return typeof e==`string`?{pattern:e}:e}exports.codeRuleSchema=t,exports.normalizeCodeRule=r,exports.problemMarkdownFrontMatterSchema=n;
|
|
2
2
|
//# sourceMappingURL=problem.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"problem.cjs","names":["z"],"sources":["../../src/types/problem.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const problemMarkdownFrontMatterSchema = z.object({\n timeLimitMs: z.number().int().min(0).optional(),\n memoryLimitByte: z.number().int().min(0).optional(),\n requiredRegExpsInCode: z.array(
|
|
1
|
+
{"version":3,"file":"problem.cjs","names":["z"],"sources":["../../src/types/problem.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * A static-analysis rule on submitted code: either a bare pattern (its regular expression or text\n * is shown to learners on violation) or a pattern with a learner-facing message that replaces it.\n * The message is rendered as one Markdown list item, so it must be a single line.\n */\nexport const codeRuleSchema = z.union([\n z.string().min(1),\n z.object({\n pattern: z.string().min(1),\n message: z\n .string()\n .min(1)\n .refine((message) => !/[\\r\\n]/.test(message), 'message must be a single line'),\n }),\n]);\n\nexport type CodeRule = z.infer<typeof codeRuleSchema>;\n\nexport const problemMarkdownFrontMatterSchema = z.object({\n timeLimitMs: z.number().int().min(0).optional(),\n memoryLimitByte: z.number().int().min(0).optional(),\n requiredRegExpsInCode: z.array(codeRuleSchema).optional(),\n forbiddenRegExpsInCode: z.array(codeRuleSchema).optional(),\n forbiddenTextsInCode: z.array(codeRuleSchema).optional(),\n isManualScoringRequired: z.boolean().optional(),\n requiredEnvironmentVariables: z.array(z.string().min(1)).optional(),\n requiredOutputFilePaths: z.array(z.string().min(1)).optional(),\n requiredSubmissionFilePaths: z.array(z.string().min(1)).optional(),\n});\n\nexport type ProblemMarkdownFrontMatter = z.infer<typeof problemMarkdownFrontMatterSchema>;\n\nexport function normalizeCodeRule(rule: CodeRule): { pattern: string; message?: string } {\n return typeof rule === 'string' ? { pattern: rule } : rule;\n}\n"],"mappings":"kCAOA,MAAa,EAAiBA,EAAAA,EAAE,MAAM,CACpCA,EAAAA,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAChBA,EAAAA,EAAE,OAAO,CACP,QAASA,EAAAA,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EACzB,QAASA,EAAAA,EACN,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,OAAQ,GAAY,CAAC,SAAS,KAAK,CAAO,EAAG,+BAA+B,CACjF,CAAC,CACH,CAAC,EAIY,EAAmCA,EAAAA,EAAE,OAAO,CACvD,YAAaA,EAAAA,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAC9C,gBAAiBA,EAAAA,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAClD,sBAAuBA,EAAAA,EAAE,MAAM,CAAc,CAAC,CAAC,SAAS,EACxD,uBAAwBA,EAAAA,EAAE,MAAM,CAAc,CAAC,CAAC,SAAS,EACzD,qBAAsBA,EAAAA,EAAE,MAAM,CAAc,CAAC,CAAC,SAAS,EACvD,wBAAyBA,EAAAA,EAAE,QAAQ,CAAC,CAAC,SAAS,EAC9C,6BAA8BA,EAAAA,EAAE,MAAMA,EAAAA,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAClE,wBAAyBA,EAAAA,EAAE,MAAMA,EAAAA,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAC7D,4BAA6BA,EAAAA,EAAE,MAAMA,EAAAA,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CACnE,CAAC,EAID,SAAgB,EAAkB,EAAuD,CACvF,OAAO,OAAO,GAAS,SAAW,CAAE,QAAS,CAAK,EAAI,CACxD"}
|
package/dist/types/problem.d.ts
CHANGED
|
@@ -1,13 +1,36 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* A static-analysis rule on submitted code: either a bare pattern (its regular expression or text
|
|
4
|
+
* is shown to learners on violation) or a pattern with a learner-facing message that replaces it.
|
|
5
|
+
* The message is rendered as one Markdown list item, so it must be a single line.
|
|
6
|
+
*/
|
|
7
|
+
export declare const codeRuleSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
8
|
+
pattern: z.ZodString;
|
|
9
|
+
message: z.ZodString;
|
|
10
|
+
}, z.core.$strip>]>;
|
|
11
|
+
export type CodeRule = z.infer<typeof codeRuleSchema>;
|
|
2
12
|
export declare const problemMarkdownFrontMatterSchema: z.ZodObject<{
|
|
3
13
|
timeLimitMs: z.ZodOptional<z.ZodNumber>;
|
|
4
14
|
memoryLimitByte: z.ZodOptional<z.ZodNumber>;
|
|
5
|
-
requiredRegExpsInCode: z.ZodOptional<z.ZodArray<z.ZodString
|
|
6
|
-
|
|
7
|
-
|
|
15
|
+
requiredRegExpsInCode: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
16
|
+
pattern: z.ZodString;
|
|
17
|
+
message: z.ZodString;
|
|
18
|
+
}, z.core.$strip>]>>>;
|
|
19
|
+
forbiddenRegExpsInCode: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
20
|
+
pattern: z.ZodString;
|
|
21
|
+
message: z.ZodString;
|
|
22
|
+
}, z.core.$strip>]>>>;
|
|
23
|
+
forbiddenTextsInCode: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
24
|
+
pattern: z.ZodString;
|
|
25
|
+
message: z.ZodString;
|
|
26
|
+
}, z.core.$strip>]>>>;
|
|
8
27
|
isManualScoringRequired: z.ZodOptional<z.ZodBoolean>;
|
|
9
28
|
requiredEnvironmentVariables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10
29
|
requiredOutputFilePaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
11
30
|
requiredSubmissionFilePaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
12
31
|
}, z.core.$strip>;
|
|
13
32
|
export type ProblemMarkdownFrontMatter = z.infer<typeof problemMarkdownFrontMatterSchema>;
|
|
33
|
+
export declare function normalizeCodeRule(rule: CodeRule): {
|
|
34
|
+
pattern: string;
|
|
35
|
+
message?: string;
|
|
36
|
+
};
|
package/dist/types/problem.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{z as e}from"zod";const t=e.object({
|
|
1
|
+
import{z as e}from"zod";const t=e.union([e.string().min(1),e.object({pattern:e.string().min(1),message:e.string().min(1).refine(e=>!/[\r\n]/.test(e),`message must be a single line`)})]),n=e.object({timeLimitMs:e.number().int().min(0).optional(),memoryLimitByte:e.number().int().min(0).optional(),requiredRegExpsInCode:e.array(t).optional(),forbiddenRegExpsInCode:e.array(t).optional(),forbiddenTextsInCode:e.array(t).optional(),isManualScoringRequired:e.boolean().optional(),requiredEnvironmentVariables:e.array(e.string().min(1)).optional(),requiredOutputFilePaths:e.array(e.string().min(1)).optional(),requiredSubmissionFilePaths:e.array(e.string().min(1)).optional()});function r(e){return typeof e==`string`?{pattern:e}:e}export{t as codeRuleSchema,r as normalizeCodeRule,n as problemMarkdownFrontMatterSchema};
|
|
2
2
|
//# sourceMappingURL=problem.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"problem.js","names":[],"sources":["../../src/types/problem.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const problemMarkdownFrontMatterSchema = z.object({\n timeLimitMs: z.number().int().min(0).optional(),\n memoryLimitByte: z.number().int().min(0).optional(),\n requiredRegExpsInCode: z.array(
|
|
1
|
+
{"version":3,"file":"problem.js","names":[],"sources":["../../src/types/problem.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * A static-analysis rule on submitted code: either a bare pattern (its regular expression or text\n * is shown to learners on violation) or a pattern with a learner-facing message that replaces it.\n * The message is rendered as one Markdown list item, so it must be a single line.\n */\nexport const codeRuleSchema = z.union([\n z.string().min(1),\n z.object({\n pattern: z.string().min(1),\n message: z\n .string()\n .min(1)\n .refine((message) => !/[\\r\\n]/.test(message), 'message must be a single line'),\n }),\n]);\n\nexport type CodeRule = z.infer<typeof codeRuleSchema>;\n\nexport const problemMarkdownFrontMatterSchema = z.object({\n timeLimitMs: z.number().int().min(0).optional(),\n memoryLimitByte: z.number().int().min(0).optional(),\n requiredRegExpsInCode: z.array(codeRuleSchema).optional(),\n forbiddenRegExpsInCode: z.array(codeRuleSchema).optional(),\n forbiddenTextsInCode: z.array(codeRuleSchema).optional(),\n isManualScoringRequired: z.boolean().optional(),\n requiredEnvironmentVariables: z.array(z.string().min(1)).optional(),\n requiredOutputFilePaths: z.array(z.string().min(1)).optional(),\n requiredSubmissionFilePaths: z.array(z.string().min(1)).optional(),\n});\n\nexport type ProblemMarkdownFrontMatter = z.infer<typeof problemMarkdownFrontMatterSchema>;\n\nexport function normalizeCodeRule(rule: CodeRule): { pattern: string; message?: string } {\n return typeof rule === 'string' ? { pattern: rule } : rule;\n}\n"],"mappings":"wBAOA,MAAa,EAAiB,EAAE,MAAM,CACpC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAChB,EAAE,OAAO,CACP,QAAS,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EACzB,QAAS,EACN,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,OAAQ,GAAY,CAAC,SAAS,KAAK,CAAO,EAAG,+BAA+B,CACjF,CAAC,CACH,CAAC,EAIY,EAAmC,EAAE,OAAO,CACvD,YAAa,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAC9C,gBAAiB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAClD,sBAAuB,EAAE,MAAM,CAAc,CAAC,CAAC,SAAS,EACxD,uBAAwB,EAAE,MAAM,CAAc,CAAC,CAAC,SAAS,EACzD,qBAAsB,EAAE,MAAM,CAAc,CAAC,CAAC,SAAS,EACvD,wBAAyB,EAAE,QAAQ,CAAC,CAAC,SAAS,EAC9C,6BAA8B,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAClE,wBAAyB,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAC7D,4BAA6B,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CACnE,CAAC,EAID,SAAgB,EAAkB,EAAuD,CACvF,OAAO,OAAO,GAAS,SAAW,CAAE,QAAS,CAAK,EAAI,CACxD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exercode/problem-utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": ":100: A set of utilities for judging programs on Exercode (https://exercode.willbooster.com/).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"exercode",
|
|
@@ -71,16 +71,16 @@
|
|
|
71
71
|
"@willbooster/oxfmt-config": "1.2.2",
|
|
72
72
|
"@willbooster/oxlint-config": "1.4.8",
|
|
73
73
|
"@willbooster/prettier-config": "10.4.0",
|
|
74
|
-
"@willbooster/wb": "22.
|
|
74
|
+
"@willbooster/wb": "22.1.2",
|
|
75
75
|
"build-ts": "21.0.9",
|
|
76
|
-
"conventional-changelog-conventionalcommits": "10.
|
|
76
|
+
"conventional-changelog-conventionalcommits": "10.4.0",
|
|
77
77
|
"lefthook": "2.1.10",
|
|
78
78
|
"oxfmt": "0.64.0",
|
|
79
79
|
"oxlint": "1.79.0",
|
|
80
80
|
"oxlint-tsgolint": "7.0.2001",
|
|
81
81
|
"prettier": "3.9.6",
|
|
82
82
|
"prettier-plugin-java": "2.10.3",
|
|
83
|
-
"puppeteer": "25.
|
|
83
|
+
"puppeteer": "25.8.0",
|
|
84
84
|
"semantic-release": "25.0.9",
|
|
85
85
|
"sort-package-json": "4.0.0",
|
|
86
86
|
"typescript": "7.0.2",
|