diff --git a/src/commands/compile.ts b/src/commands/compile.ts index 2baae5a..f47b89c 100644 --- a/src/commands/compile.ts +++ b/src/commands/compile.ts @@ -56,8 +56,7 @@ the package.json file under the \`publicodes\` key. For example: static override flags = { output: Flags.string({ char: 'o', - default: 'build', - summary: 'Specify the output directory.', + summary: 'Specify the output directory. Default is "./build".', }), } @@ -67,7 +66,8 @@ the package.json file under the \`publicodes\` key. For example: p.intro(chalk.bgHex('#2975d1')(' publicodes compile ')) const filesToCompile: string[] = argv.length === 0 - ? this.config.pjson?.publicodes?.files ?? ['src/'] + ? // TODO: test with production package + this.config.pjson?.publicodes?.files ?? ['src/'] : argv const outputDir = path.resolve( @@ -93,9 +93,14 @@ the package.json file under the \`publicodes\` key. For example: async generateDTS(engine: Engine, outputDir: string): Promise { return runWithSpinner('Generating types', 'Types generated.', () => { const ruleTypes = resolveRuleTypes(engine) - const serializedRuleTypes = Object.entries(ruleTypes) + const typesEntries = Object.entries(ruleTypes) + const serializedRuleTypes = typesEntries .map(([name, type]) => ` "${name}": ${serializeType(type)}`) .join(',\n') + const serializedQuestionsRuleTypes = typesEntries + .filter(([name]) => engine.getRule(name).rawNode.question) + .map(([name, type]) => ` "${name}": ${serializeJSType(type)}`) + .join(',\n') const dts = `/** THIS FILE WAS GENERATED BY ${this.config.pjson.name} (v${this.config.pjson.version}). PLEASE, DO NOT EDIT IT MANUALLY. */ @@ -119,15 +124,33 @@ export type PString = \`'\${string}'\` /** * Corresponding Publicodes situation with types inferred for each rule. + * + * @note + * This represents the situation as needed by the 'setSituation' method of the + * {@link Engine} class with raw values (i.e. string constants are enclosed in + * "''" and boolean values are 'oui' or 'non'). */ -export type TypedSituation = { +export type Situation = Partial<{ ${serializedRuleTypes} -} +}> + +/** + * Subset of the {@link Situation} with only the rules that are questions + * (i.e. input rules). + * + * @note + * This represents the input rules expected to be provided by the user. + * Therefore the values are in their JavaScript form (i.e. string constants are + * enclosed in '' and boolean values are 'true' or 'false'). + */ +export type Questions = Partial<{ +${serializedQuestionsRuleTypes} +}> /** * All rule names available in the model. */ -export type RuleName = keyof TypedSituation +export type RuleName = keyof Situation declare let rules: Record @@ -237,3 +260,24 @@ function serializeType(type: RuleType): string { } } } + +function serializeJSType(type: RuleType): string { + const nullable = type.isNullable ? ' | null' : '' + switch (type.type) { + case 'string': { + return `string${nullable}` + } + case 'number': { + return `number${nullable}` + } + case 'boolean': { + return `boolean${nullable}` + } + case 'date': { + return `string${nullable}` + } + case 'enum': { + return type.options.map((option) => `"${option}"`).join(' | ') + nullable + } + } +} diff --git a/src/commands/init.ts b/src/commands/init.ts index af7e368..2538203 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -1,4 +1,4 @@ -import fs from 'fs' +import fs, { appendFileSync } from 'fs' import path from 'path' import { execSync } from 'node:child_process' import { Command, Flags } from '@oclif/core' @@ -141,6 +141,10 @@ installation.`, pkgJSON.description = pkgJSON.description ?? basePackageJson.description pkgJSON.author = pkgJSON.author ?? basePackageJson.author pkgJSON.files = basePackageJson.files!.concat(pkgJSON.files ?? []) + pkgJSON.scripts = { + ...pkgJSON.scripts, + ...basePackageJson.scripts, + } pkgJSON.peerDependencies = { ...pkgJSON.peerDependencies, ...basePackageJson.peerDependencies, @@ -150,10 +154,6 @@ installation.`, // NOTE: to test with the packaged version '@publicodes/tools': `^${this.config.pjson.version}`, } - pkgJSON.scripts = { - ...pkgJSON.scripts, - ...basePackageJson.scripts, - } if (pkgJSON.name.startsWith('@')) { pkgJSON.publishConfig = { access: 'public' } } @@ -269,7 +269,7 @@ function setupTests(pkgJSON: PackageJson) { } pkgJSON.scripts = { ...pkgJSON.scripts, - test: 'vitest --globals', + test: 'vitest run --globals', } return pkgJSON } @@ -343,6 +343,11 @@ async function generateBaseFiles( ) } + fs.appendFileSync( + '.gitattributes', + '*.publicodes linguist-language=YAML\n', + ) + if (!fs.existsSync('test')) { fs.mkdirSync('test') } diff --git a/src/utils/pjson.ts b/src/utils/pjson.ts index d2cf1e3..c6f3d59 100644 --- a/src/utils/pjson.ts +++ b/src/utils/pjson.ts @@ -30,6 +30,10 @@ export type PackageJson = { publishConfig?: { access: string } + publicodes?: { + files?: string[] + output?: string + } } export const basePackageJson: PackageJson = {