Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDK v2 #3024

Closed
wants to merge 40 commits into from
Closed

SDK v2 #3024

Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
5e1efe9
WIP - api with types before exposing kisly directly
martin-lysk Jul 19, 2024
cb68b78
cleanup
martin-lysk Jul 19, 2024
a1505ac
message-bundle-component -> bundle-component
martin-lysk Jul 22, 2024
1114ca5
WIP lifting bundle-component to sdk v2
martin-lysk Jul 22, 2024
f33bf71
updates bundle-component to sdk-v2
martin-lysk Jul 22, 2024
e9e24c9
WIP SDKv2 added, sample app misses crud still
martin-lysk Jul 22, 2024
2dbed05
feat: add reactive pattern test story
NilsJacobsen Jul 22, 2024
e9c3a0d
fixes on change
martin-lysk Jul 22, 2024
099011b
Merge branch 'martinlysk1/mesdk-154-main' of github.com:opral/monorep…
martin-lysk Jul 22, 2024
0b9d4a6
fixes reactivty of pattern editor
martin-lysk Jul 22, 2024
28cc8f1
WIP - non reactivity Version of crud working
martin-lysk Jul 22, 2024
a5eb2aa
cleanup
martin-lysk Jul 24, 2024
2cd68ce
fixes new project call
martin-lysk Jul 24, 2024
97a8492
adds polling to list messages query
martin-lysk Jul 24, 2024
d226964
feat: add new type for match & adjust component
NilsJacobsen Jul 25, 2024
850641d
todo cleanup
martin-lysk Jul 25, 2024
5d81ec9
Merge branch 'martinlysk1/mesdk-154-main' of github.com:opral/monorep…
martin-lysk Jul 25, 2024
be1794b
feat: add new lint mocks to bundle component in storybook
NilsJacobsen Jul 26, 2024
97f6e3e
fix: selector delete
NilsJacobsen Jul 26, 2024
aac7522
fix: lint report resolution of variants
NilsJacobsen Jul 26, 2024
f3ed675
fix: delete index/name
NilsJacobsen Jul 26, 2024
f3aff5a
fix: css foreground of lint reports
NilsJacobsen Jul 26, 2024
967284c
Merge pull request #3034 from opral/nilsjacobsen/inlmc-138-add-new-li…
NilsJacobsen Jul 26, 2024
8a82cee
introduce importer/exporter to plugin API
felixhaeberle Jul 29, 2024
91c72c0
update reference in code
felixhaeberle Jul 29, 2024
d93f29f
update plugin error types
felixhaeberle Jul 29, 2024
e8bdeb8
update plugin error type usage in plugin API
felixhaeberle Jul 29, 2024
ea97203
refactor type naming
felixhaeberle Jul 29, 2024
5743ea6
reimplement resolve plugin behavior
felixhaeberle Jul 29, 2024
30907d5
update crud helper types
felixhaeberle Jul 29, 2024
f203fdc
fix message bundle type errors
felixhaeberle Jul 29, 2024
23908a9
fix testing lint rules types
felixhaeberle Jul 29, 2024
fd41ed9
refactor types to handle multiple importer / exporter
felixhaeberle Jul 29, 2024
3d5c782
update resolveModules2 & resolvePlugins2
felixhaeberle Jul 29, 2024
3b842d1
start update import & loadProject & remove concept of `InlangModule` …
felixhaeberle Jul 29, 2024
5303f85
update code comment
felixhaeberle Jul 29, 2024
936e031
progress on remove concept of `Module` in favor of only `Plugin` beca…
felixhaeberle Jul 29, 2024
66f6b57
Merge branch 'martinlysk1/mesdk-154-main' of github.com:opral/monorep…
martin-lysk Jul 29, 2024
03a274c
fix: don't show report when bundleValidationReports are empty
NilsJacobsen Jul 30, 2024
36a9750
Merge branch 'martinlysk1/mesdk-154-main' of github.com:opral/monorep…
martin-lysk Jul 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 42 additions & 30 deletions inlang/source-code/sdk-v2/src/types/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import {
import type { JSONObject } from "@inlang/json-types"
import type { CustomApiInlangIdeExtension } from "./customApis/app.inlang.ideExtension.js"
import { Translatable } from "@inlang/translatable"
import type { ProjectSettings2, ExternalProjectSettings } from "./project-settings.js"
import {
type ProjectSettings2 as ProjectSettings2Type,
type ExternalProjectSettings as ExternalProjectSettingsType,
ExternalProjectSettings,
} from "./project-settings.js"
import type {
PluginHasInvalidIdError,
PluginHasInvalidSchemaError,
Expand All @@ -17,6 +21,8 @@ import type {
PluginSaveMessagesFunctionAlreadyDefinedError,
PluginsDoNotProvideLoadOrSaveMessagesError,
} from "./plugin-errors.js"
import { NestedBundle } from "./schema.js"
import { TranslationFile, type TranslationFile as TranslationFileType } from "./translation-file.js"

// ---------------------------- RUNTIME VALIDATION TYPES ---------------------------------------------

Expand All @@ -36,26 +42,24 @@ import type {
* ```
*/
export type Plugin2<
ExternalSettings extends Record<keyof ExternalProjectSettings, JSONObject> | unknown = unknown
ExternalSettings extends Record<keyof ExternalProjectSettingsType, JSONObject> | unknown = unknown
> = Omit<
Static<typeof Plugin2>,
"loadMessages" | "saveMessages" | "addCustomApi" | "settingsSchema"
"toBeImportedFiles" | "importFiles" | "exportFiles" | "addCustomApi" | "settingsSchema"
> & {
settingsSchema?: TObject
/**
* Load messages.
* Import / Export files.
*/
// TODO SDK-V2 check how to setup loadMessages
// loadMessages?: (args: {
// settings: ProjectSettings2 & ExternalSettings
// // nodeishFs: NodeishFilesystemSubset
// }) => Promise<Message[]> | Message[]
// TODO SDK-V2 check how to setup saveMessages
// saveMessages?: (args: {
// // messages: Message[]
// settings: ProjectSettings2 & ExternalSettings
// // nodeishFs: NodeishFilesystemSubset
// }) => Promise<void> | void
toBeImportedFiles?: (args: {
settings: ProjectSettings2Type & ExternalSettings
nodeFs: unknown
}) => Promise<Array<TranslationFileType>> | Array<TranslationFileType>
importFiles?: (args: { files: Array<TranslationFileType> }) => { bundles: NestedBundle }
exportFiles?: (args: {
bundles: NestedBundle
settings: ProjectSettings2Type & ExternalSettings
}) => Array<TranslationFileType>
/**
* Define app specific APIs.
*
Expand All @@ -67,7 +71,7 @@ export type Plugin2<
* })
*/
addCustomApi?: (args: {
settings: ProjectSettings2 & ExternalSettings
settings: ProjectSettings2Type & ExternalSettings
}) =>
| Record<`app.${string}.${string}`, unknown>
| { "app.inlang.ideExtension": CustomApiInlangIdeExtension }
Expand All @@ -86,8 +90,24 @@ export const Plugin2 = Type.Object({
* https://github.com/opral/monorepo/discussions/1503
*/
settingsSchema: Type.Optional(Type.Object({}, { additionalProperties: true })),
loadMessages: Type.Optional(Type.Any()),
saveMessages: Type.Optional(Type.Any()),
toBeImportedFiles: Type.Optional(
Type.Function(
[Type.Object({ settings: ExternalProjectSettings, nodeFs: Type.Any() })],
Type.Array(TranslationFile)
)
),
importFiles: Type.Optional(
Type.Function(
[Type.Object({ files: Type.Array(TranslationFile) })],
Type.Object({ bundles: NestedBundle })
)
),
exportFiles: Type.Optional(
Type.Function(
[Type.Object({ bundles: NestedBundle, settings: ExternalProjectSettings })],
Type.Array(TranslationFile)
)
),
/**
* @deprecated removed
*/
Expand All @@ -100,7 +120,7 @@ export const Plugin2 = Type.Object({
*/
export type ResolvePlugins2Function = (args: {
plugins: Array<Plugin2>
settings: ProjectSettings2
settings: ProjectSettings2Type
}) => Promise<{
data: ResolvedPlugin2Api
errors: Array<
Expand All @@ -117,17 +137,9 @@ export type ResolvePlugins2Function = (args: {
* The API after resolving the plugins.
*/
export type ResolvedPlugin2Api = {
// TODO SDK-V2 check how to setup loadMessages
// loadMessages: (args: {
// settings: ProjectSettings2
// nodeishFs: NodeishFilesystemSubset
// }) => Promise<Message[]> | Message[]
// TODO SDK-V2 check how to setup saveMessages
// saveMessages: (args: {
// settings: ProjectSettings2
// messages: Message[]
// nodeishFs: NodeishFilesystemSubset
// }) => Promise<void> | void
toBeImportedFiles: Array<Plugin2["toBeImportedFiles"]>
importFiles: Array<Plugin2["importFiles"]>
exportFiles: Array<Plugin2["exportFiles"]>
felixhaeberle marked this conversation as resolved.
Show resolved Hide resolved
/**
* App specific APIs.
*
Expand Down
216 changes: 115 additions & 101 deletions inlang/source-code/sdk-v2/src/types/schema.ts
Original file line number Diff line number Diff line change
@@ -1,113 +1,127 @@
import type { Insertable, JSONColumnType, Selectable, Updateable } from "kysely"

import { Type, type Static } from "@sinclair/typebox"
import type { Insertable, Selectable, Updateable } from "kysely"
import type { LintReport } from "./lint.js"

export type Database = {
bundle: BundleTable
message: MessageTable
variant: VariantTable

lintReport: LintReport
// todo - move out of database
settings: Settings
}

type AliasMap = {
[key: string]: string
}

// Bundles all languages of a message -
type BundleTable = {
id: string
// todo make alias relational
alias: JSONColumnType<AliasMap> // alias usually have a property "default" that represents the message name like "welcome_message" or "login_button"
// messages[] @relation
// messages: Message[]
export const VariableReference = Type.Object({
type: Type.Literal("variable"),
name: Type.String(),
})

export const Literal = Type.Object({
type: Type.Literal("literal"),
name: Type.String(),
})

export const Option = Type.Object({
name: Type.String(),
value: Type.Union([Literal, VariableReference]),
})

const FunctionAnnotation = Type.Object({
type: Type.Literal("function"),
name: Type.String(),
options: Type.Array(Option),
})

export const Expression = Type.Object({
type: Type.Literal("expression"),
arg: Type.Union([VariableReference, Literal]),
annotation: Type.Optional(FunctionAnnotation),
})

export const Text = Type.Object({
type: Type.Literal("text"),
value: Type.String(),
})

export const Declaration = Type.Object({
type: Type.Literal("input"),
name: Type.String(),
value: Expression,
})

export const Pattern = Type.Array(Type.Union([Text, Expression]))

export const Settings = Type.Object({
baseLocale: Type.String(),
locales: Type.String(),
modules: Type.String(),
})

export const BundleTable = Type.Object({
id: Type.String(),
alias: Type.Any(), // TODO: Use appropriate Typebox type for JSONColumnType<AliasMap>
})

export const MessageTable = Type.Object({
id: Type.String(),
bundleId: Type.String(),
locale: Type.String(),
declarations: Type.Any(), // TODO: Use appropriate Typebox type for JSONColumnType<Declaration[]>
selectors: Type.Any(), // TODO: Use appropriate Typebox type for JSONColumnType<Expression[]>
})
felixhaeberle marked this conversation as resolved.
Show resolved Hide resolved

export const VariantTable = Type.Object({
id: Type.String(),
messageId: Type.String(),
match: Type.Any(), // TODO: Use appropriate Typebox type for JSONColumnType<Record<Expression["arg"]["name"], string>>
pattern: Type.Any(), // TODO: Use appropriate Typebox type for JSONColumnType<Pattern>
})

export const NestedMessage = Type.Object({
id: Type.String(),
locale: Type.String(),
declarations: Type.Any(), // TODO: Use appropriate Typebox type for JSONColumnType<Declaration[]>
selectors: Type.Any(), // TODO: Use appropriate Typebox type for JSONColumnType<Expression[]>
variants: Type.Array(VariantTable),
})

export const NestedBundle = Type.Object({
id: Type.String(),
alias: Type.Any(), // TODO: Use appropriate Typebox type for JSONColumnType<AliasMap>
messages: Type.Array(NestedMessage),
})

// Export types
export type BundleTableType = Static<typeof BundleTable>
export type MessageTableType = Static<typeof MessageTable>
export type VariantTableType = Static<typeof VariantTable>

export type Bundle = Selectable<BundleTableType>

export type NestedMessage = Selectable<MessageTableType> & {
variants: Selectable<VariantTableType>[]
}

type MessageTable = {
id: string
// @relation to Bundle
bundleId: BundleTable["id"]
locale: string
declarations: JSONColumnType<Declaration[]> // JSON
selectors: JSONColumnType<Expression[]> // JSON
// variants: Variant[]
}

type VariantTable = {
id: string
// @relation to Message
messageId: MessageTable["id"]
match: JSONColumnType<Record<Expression["arg"]["name"], string>>
pattern: JSONColumnType<Pattern> // JSON
}

export type Bundle = Selectable<BundleTable>

export type NestedMessage = Message & {
variants: Variant[]
}

export type NestedBundle = Bundle & {
export type NestedBundle = Selectable<BundleTableType> & {
messages: NestedMessage[]
}

export type NewBundle = Insertable<BundleTable>
export type UpdatedBundle = Updateable<BundleTable>

export type Message = Selectable<MessageTable>
export type NewMessage = Insertable<MessageTable>
export type UpdatedMessage = Updateable<MessageTable>

export type Variant = Selectable<VariantTable>
export type NewVariant = Insertable<VariantTable>
export type UpdatedVariant = Updateable<VariantTable>

export type Pattern = Array<Text | Expression>

export type Text = {
type: "text"
value: string
}

export type VariableReference = {
type: "variable"
name: string
}

export type Literal = {
type: "literal"
name: string
}

export type Declaration = InputDeclaration

export type InputDeclaration = {
type: "input"
name: string
value: Expression
}
export type NewBundle = Insertable<BundleTableType>
export type UpdatedBundle = Updateable<BundleTableType>

export type Expression = {
type: "expression"
arg: VariableReference | Literal
annotation?: FunctionAnnotation
}
export type Message = Selectable<MessageTableType>
export type NewMessage = Insertable<MessageTableType>
export type UpdatedMessage = Updateable<MessageTableType>

export type FunctionAnnotation = {
type: "function"
name: string
options: Option[]
}
export type Variant = Selectable<VariantTableType>
export type NewVariant = Insertable<VariantTableType>
export type UpdatedVariant = Updateable<VariantTableType>

export type Option = {
name: string
value: Literal | VariableReference
}
export type PatternType = Static<typeof Pattern>
export type TextType = Static<typeof Text>
export type VariableReferenceType = Static<typeof VariableReference>
export type LiteralType = Static<typeof Literal>
export type DeclarationType = Static<typeof Declaration>
export type ExpressionType = Static<typeof Expression>
export type FunctionAnnotationType = Static<typeof FunctionAnnotation>
export type OptionType = Static<typeof Option>
export type SettingsType = Static<typeof Settings>

export type Settings = {
baseLocale: string
locales: string
modules: string
export type Database = {
bundle: Static<typeof BundleTable>
message: Static<typeof MessageTable>
variant: Static<typeof VariantTable>
lintReport: LintReport
settings: Static<typeof Settings>
}
9 changes: 9 additions & 0 deletions inlang/source-code/sdk-v2/src/types/translation-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Type, type Static } from "@sinclair/typebox"

export const TranslationFile = Type.Object({
path: Type.String(),
content: Type.String(),
pluginKey: Type.String(),
})

export type TranslationFile = Static<typeof TranslationFile>
Loading