Skip to content

Commit

Permalink
support additional properties in RLC (#2054)
Browse files Browse the repository at this point in the history
* try-fix-model-inherit-from-record

* reserve work

* fix record extends

* fix modular literal error

* fix ut error

* fix ci

* add more ut

* resolve comments

* use handle is record

* fix lint error

* fix ci failure
  • Loading branch information
qiaozha authored Oct 17, 2023
1 parent f2ea726 commit dcaaee9
Show file tree
Hide file tree
Showing 13 changed files with 738 additions and 167 deletions.
2 changes: 1 addition & 1 deletion packages/rlc-common/src/buildIndexFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ function generateRLCIndex(file: SourceFile, model: RLCModel) {
hasMultiCollection(model) ||
hasSsvCollection(model) ||
hasPipeCollection(model) ||
hasTsvCollection(model) ||
hasTsvCollection(model) ||
hasCsvCollection(model)
) {
file.addExportDeclarations([
Expand Down
24 changes: 16 additions & 8 deletions packages/rlc-common/src/buildObjectTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,24 +363,32 @@ function getImmediateParentsNames(

const extendFrom: string[] = [];

// If an immediate parent is a DictionarySchema, that means that the object has been marked
// If an immediate parent is an empty DictionarySchema, that means that the object has been marked
// with additional properties. We need to add Record<string, unknown> to the extend list and
if (objectSchema.parents.immediate.find(isDictionarySchema)) {
if (
objectSchema.parents.immediate.find((im) => isDictionarySchema(im, {filterEmpty: true}))
) {
extendFrom.push("Record<string, unknown>");
}

// Get the rest of the parents excluding any DictionarySchemas
const parents = objectSchema.parents.immediate
.filter((p) => !isDictionarySchema(p))
.filter((p) => !isDictionarySchema(p, {filterEmpty: true}))
.map((parent) => {
const nameSuffix = schemaUsage.includes(SchemaContext.Output)
? "Output"
: "";
const name = `${normalizeName(
parent.name,
NameType.Interface,
true /** shouldGuard */
)}${nameSuffix}`;
const name = isDictionarySchema(parent)
? `${
(schemaUsage.includes(SchemaContext.Output)
? parent.outputTypeName
: parent.typeName) ?? parent.name
}`
: `${normalizeName(
parent.name,
NameType.Interface,
true /** shouldGuard */
)}${nameSuffix}`;

return isObjectSchema(parent) && isPolymorphicParent(parent)
? `${name}Parent`
Expand Down
13 changes: 11 additions & 2 deletions packages/rlc-common/src/helpers/schemaHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,18 @@

import { Schema } from "../interfaces.js";

export function isDictionarySchema(schema: Schema) {
export interface IsDictionaryOptions {
filterEmpty?: boolean;
}

export function isDictionarySchema(
schema: Schema,
options: IsDictionaryOptions = {}
) {
if (schema.type === "dictionary") {
return true;
if (!options.filterEmpty || (options.filterEmpty && !schema.typeName)) {
return true;
}
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ export interface Project {
language: string;
multilingual?: boolean;
projectKind: "CustomSingleLabelClassification" | "CustomMultiLabelClassification" | "CustomEntityRecognition";
settings?: Record<string, string>;
settings?: ProjectSettings;
storageInputContainerName: string;
}

Expand All @@ -774,13 +774,21 @@ export interface ProjectOutput {
multilingual?: boolean;
projectKind: "CustomSingleLabelClassification" | "CustomMultiLabelClassification" | "CustomEntityRecognition";
readonly projectName: string;
settings?: Record<string, string>;
settings?: ProjectSettingsOutput;
storageInputContainerName: string;
}

// @public
export type ProjectResourceMergeAndPatch = Partial<Project>;

// @public
export interface ProjectSettings extends Record<string, string> {
}

// @public
export interface ProjectSettingsOutput extends Record<string, string> {
}

// @public (undocumented)
export interface Routes {
(path: "/authoring/analyze-text/projects/{projectName}", projectName: string): CreateOrUpdate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface Project {
/** The storage container name. */
storageInputContainerName: string;
/** The project settings. */
settings?: Record<string, string>;
settings?: ProjectSettings;
/** Whether the project would be used for multiple languages or not. */
multilingual?: boolean;
/** The project description. */
Expand All @@ -20,6 +20,9 @@ export interface Project {
language: string;
}

/** Represents the settings used to define the project behavior. */
export interface ProjectSettings extends Record<string, string> {}

/** Training job parameters. */
export interface TrainingJobOptions {
/** The model label. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface ProjectOutput {
/** The storage container name. */
storageInputContainerName: string;
/** The project settings. */
settings?: Record<string, string>;
settings?: ProjectSettingsOutput;
/** Whether the project would be used for multiple languages or not. */
multilingual?: boolean;
/** The project description. */
Expand All @@ -33,6 +33,9 @@ export interface ProjectOutput {
readonly lastDeployedDateTime: string;
}

/** Represents the settings used to define the project behavior. */
export interface ProjectSettingsOutput extends Record<string, string> {}

/** Provides status details for long running operations. */
export interface OperationStatusOutput {
/** The unique ID of the operation. */
Expand Down
6 changes: 5 additions & 1 deletion packages/typespec-ts/src/modular/emitModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,11 @@ export function buildModelsOptions(
client: Client
) {
const modelOptionsFile = codeModel.project.createSourceFile(
`${codeModel.modularOptions.sourceRoot}/${client.subfolder}/models/options.ts`,
path.join(
codeModel.modularOptions.sourceRoot,
client.subfolder ?? "",
`models/options.ts`
),
undefined,
{
overwrite: true
Expand Down
2 changes: 1 addition & 1 deletion packages/typespec-ts/src/modular/helpers/typeHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function getType(type: Type, format?: string): TypeMetadata {
case "boolean":
return { name: getNullableType(type.type, type) };
case "constant": {
let typeName: string = type.value ?? "undefined";
let typeName: string = type.value?.toString() ?? "undefined";
if (type.valueType?.type === "string") {
typeName = type.value ? `"${type.value}"` : "undefined";
}
Expand Down
8 changes: 6 additions & 2 deletions packages/typespec-ts/src/transform/transformSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,12 @@ export function transformSchemas(

setModelMap(model, context);
const indexer = (model as Model).indexer;
if (indexer?.value && !program.stateMap(modelKey).get(indexer?.value)) {
setModelMap(indexer.value, context);
if (
indexer?.value &&
(!program.stateMap(modelKey).get(indexer?.value) ||
!program.stateMap(modelKey).get(indexer?.value)?.includes(context))
) {
getGeneratedModels(indexer.value, context);
}
for (const prop of model.properties) {
if (
Expand Down
Loading

0 comments on commit dcaaee9

Please sign in to comment.