mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
fix: index template versions by template and name (#5993)
* fix: index template versions by template and name We were incorrectly returning template versions by name relative to organizations. This could result in an incorrect version being returned if multiple templates had versions with the same name. * Fix auth referencing * Fix route location * Fix authorize route name * Fix previous call * Fix authorize route name
This commit is contained in:
Generated
+98
-84
@@ -1330,6 +1330,104 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/templates/{templatename}/versions/{templateversionname}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Templates"
|
||||
],
|
||||
"summary": "Get template version by organization, template, and name",
|
||||
"operationId": "get-template-version-by-organization-template-and-name",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Organization ID",
|
||||
"name": "organization",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Template name",
|
||||
"name": "templatename",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Template version name",
|
||||
"name": "templateversionname",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.TemplateVersion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Templates"
|
||||
],
|
||||
"summary": "Get previous template version by organization, template, and name",
|
||||
"operationId": "get-previous-template-version-by-organization-template-and-name",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Organization ID",
|
||||
"name": "organization",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Template name",
|
||||
"name": "templatename",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Template version name",
|
||||
"name": "templateversionname",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.TemplateVersion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/templateversions": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -1377,90 +1475,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/templateversions/{templateversionname}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Templates"
|
||||
],
|
||||
"summary": "Get template version by organization and name",
|
||||
"operationId": "get-template-version-by-organization-and-name",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Organization ID",
|
||||
"name": "organization",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Template version name",
|
||||
"name": "templateversionname",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.TemplateVersion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/templateversions/{templateversionname}/previous": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Templates"
|
||||
],
|
||||
"summary": "Get previous template version by organization and name",
|
||||
"operationId": "get-previous-template-version-by-organization-and-name",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Organization ID",
|
||||
"name": "organization",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Template version name",
|
||||
"name": "templateversionname",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.TemplateVersion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/parameters/{scope}/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
||||
Generated
+90
-76
@@ -1160,6 +1160,96 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/templates/{templatename}/versions/{templateversionname}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Templates"],
|
||||
"summary": "Get template version by organization, template, and name",
|
||||
"operationId": "get-template-version-by-organization-template-and-name",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Organization ID",
|
||||
"name": "organization",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Template name",
|
||||
"name": "templatename",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Template version name",
|
||||
"name": "templateversionname",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.TemplateVersion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Templates"],
|
||||
"summary": "Get previous template version by organization, template, and name",
|
||||
"operationId": "get-previous-template-version-by-organization-template-and-name",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Organization ID",
|
||||
"name": "organization",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Template name",
|
||||
"name": "templatename",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Template version name",
|
||||
"name": "templateversionname",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.TemplateVersion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/templateversions": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -1201,82 +1291,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/templateversions/{templateversionname}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Templates"],
|
||||
"summary": "Get template version by organization and name",
|
||||
"operationId": "get-template-version-by-organization-and-name",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Organization ID",
|
||||
"name": "organization",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Template version name",
|
||||
"name": "templateversionname",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.TemplateVersion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/organizations/{organization}/templateversions/{templateversionname}/previous": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Templates"],
|
||||
"summary": "Get previous template version by organization and name",
|
||||
"operationId": "get-previous-template-version-by-organization-and-name",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Organization ID",
|
||||
"name": "organization",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Template version name",
|
||||
"name": "templateversionname",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.TemplateVersion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/parameters/{scope}/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
||||
+8
-6
@@ -398,16 +398,18 @@ func New(options *Options) *API {
|
||||
httpmw.ExtractOrganizationParam(options.Database),
|
||||
)
|
||||
r.Get("/", api.organization)
|
||||
r.Route("/templateversions", func(r chi.Router) {
|
||||
r.Post("/", api.postTemplateVersionsByOrganization)
|
||||
r.Get("/{templateversionname}", api.templateVersionByOrganizationAndName)
|
||||
r.Get("/{templateversionname}/previous", api.previousTemplateVersionByOrganizationAndName)
|
||||
})
|
||||
r.Post("/templateversions", api.postTemplateVersionsByOrganization)
|
||||
r.Route("/templates", func(r chi.Router) {
|
||||
r.Post("/", api.postTemplateByOrganization)
|
||||
r.Get("/", api.templatesByOrganization)
|
||||
r.Get("/{templatename}", api.templateByOrganizationAndName)
|
||||
r.Get("/examples", api.templateExamples)
|
||||
r.Route("/{templatename}", func(r chi.Router) {
|
||||
r.Get("/", api.templateByOrganizationAndName)
|
||||
r.Route("/versions/{templateversionname}", func(r chi.Router) {
|
||||
r.Get("/", api.templateVersionByOrganizationTemplateAndName)
|
||||
r.Get("/previous", api.previousTemplateVersionByOrganizationTemplateAndName)
|
||||
})
|
||||
})
|
||||
})
|
||||
r.Route("/members", func(r chi.Router) {
|
||||
r.Get("/roles", api.assignableOrgRoles)
|
||||
|
||||
@@ -239,6 +239,14 @@ func AGPLRoutes(a *AuthTester) (map[string]string, map[string]RouteCheck) {
|
||||
AssertAction: rbac.ActionRead,
|
||||
AssertObject: templateObj,
|
||||
},
|
||||
"GET:/api/v2/organizations/{organization}/templates/{templatename}/versions/{templateversionname}": {
|
||||
AssertAction: rbac.ActionRead,
|
||||
AssertObject: templateObj,
|
||||
},
|
||||
"GET:/api/v2/organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous": {
|
||||
AssertAction: rbac.ActionRead,
|
||||
AssertObject: templateObj,
|
||||
},
|
||||
"POST:/api/v2/organizations/{organization}/members/{user}/workspaces": {
|
||||
AssertAction: rbac.ActionCreate,
|
||||
// No ID when creating
|
||||
@@ -252,12 +260,10 @@ func AGPLRoutes(a *AuthTester) (map[string]string, map[string]RouteCheck) {
|
||||
"GET:/api/v2/applications/auth-redirect": {AssertAction: rbac.ActionCreate, AssertObject: rbac.ResourceAPIKey},
|
||||
|
||||
// These endpoints need payloads to get to the auth part. Payloads will be required
|
||||
"PUT:/api/v2/users/{user}/roles": {StatusCode: http.StatusBadRequest, NoAuthorize: true},
|
||||
"PUT:/api/v2/organizations/{organization}/members/{user}/roles": {NoAuthorize: true},
|
||||
"POST:/api/v2/workspaces/{workspace}/builds": {StatusCode: http.StatusBadRequest, NoAuthorize: true},
|
||||
"POST:/api/v2/organizations/{organization}/templateversions": {StatusCode: http.StatusBadRequest, NoAuthorize: true},
|
||||
"GET:/api/v2/organizations/{organization}/templateversions/{templateversionname}": {StatusCode: http.StatusBadRequest, NoAuthorize: true},
|
||||
"GET:/api/v2/organizations/{organization}/templateversions/{templateversionname}/previous": {StatusCode: http.StatusBadRequest, NoAuthorize: true},
|
||||
"PUT:/api/v2/users/{user}/roles": {StatusCode: http.StatusBadRequest, NoAuthorize: true},
|
||||
"PUT:/api/v2/organizations/{organization}/members/{user}/roles": {NoAuthorize: true},
|
||||
"POST:/api/v2/workspaces/{workspace}/builds": {StatusCode: http.StatusBadRequest, NoAuthorize: true},
|
||||
"POST:/api/v2/organizations/{organization}/templateversions": {StatusCode: http.StatusBadRequest, NoAuthorize: true},
|
||||
|
||||
// Endpoints that use the SQLQuery filter.
|
||||
"GET:/api/v2/workspaces/": {
|
||||
|
||||
@@ -1797,26 +1797,6 @@ func (q *fakeQuerier) GetTemplateVersionParameters(_ context.Context, templateVe
|
||||
return parameters, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetTemplateVersionByOrganizationAndName(_ context.Context, arg database.GetTemplateVersionByOrganizationAndNameParams) (database.TemplateVersion, error) {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return database.TemplateVersion{}, err
|
||||
}
|
||||
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
for _, templateVersion := range q.templateVersions {
|
||||
if templateVersion.OrganizationID != arg.OrganizationID {
|
||||
continue
|
||||
}
|
||||
if !strings.EqualFold(templateVersion.Name, arg.Name) {
|
||||
continue
|
||||
}
|
||||
return templateVersion, nil
|
||||
}
|
||||
return database.TemplateVersion{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetTemplateVersionByID(_ context.Context, templateVersionID uuid.UUID) (database.TemplateVersion, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
@@ -84,7 +84,6 @@ type sqlcQuerier interface {
|
||||
GetTemplateDAUs(ctx context.Context, templateID uuid.UUID) ([]GetTemplateDAUsRow, error)
|
||||
GetTemplateVersionByID(ctx context.Context, id uuid.UUID) (TemplateVersion, error)
|
||||
GetTemplateVersionByJobID(ctx context.Context, jobID uuid.UUID) (TemplateVersion, error)
|
||||
GetTemplateVersionByOrganizationAndName(ctx context.Context, arg GetTemplateVersionByOrganizationAndNameParams) (TemplateVersion, error)
|
||||
GetTemplateVersionByTemplateIDAndName(ctx context.Context, arg GetTemplateVersionByTemplateIDAndNameParams) (TemplateVersion, error)
|
||||
GetTemplateVersionParameters(ctx context.Context, templateVersionID uuid.UUID) ([]TemplateVersionParameter, error)
|
||||
GetTemplateVersionsByIDs(ctx context.Context, ids []uuid.UUID) ([]TemplateVersion, error)
|
||||
|
||||
@@ -3731,38 +3731,6 @@ func (q *sqlQuerier) GetTemplateVersionByJobID(ctx context.Context, jobID uuid.U
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getTemplateVersionByOrganizationAndName = `-- name: GetTemplateVersionByOrganizationAndName :one
|
||||
SELECT
|
||||
id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by
|
||||
FROM
|
||||
template_versions
|
||||
WHERE
|
||||
organization_id = $1
|
||||
AND "name" = $2
|
||||
`
|
||||
|
||||
type GetTemplateVersionByOrganizationAndNameParams struct {
|
||||
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) GetTemplateVersionByOrganizationAndName(ctx context.Context, arg GetTemplateVersionByOrganizationAndNameParams) (TemplateVersion, error) {
|
||||
row := q.db.QueryRowContext(ctx, getTemplateVersionByOrganizationAndName, arg.OrganizationID, arg.Name)
|
||||
var i TemplateVersion
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.TemplateID,
|
||||
&i.OrganizationID,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Name,
|
||||
&i.Readme,
|
||||
&i.JobID,
|
||||
&i.CreatedBy,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getTemplateVersionByTemplateIDAndName = `-- name: GetTemplateVersionByTemplateIDAndName :one
|
||||
SELECT
|
||||
id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by
|
||||
|
||||
@@ -52,15 +52,6 @@ WHERE
|
||||
template_id = $1
|
||||
AND "name" = $2;
|
||||
|
||||
-- name: GetTemplateVersionByOrganizationAndName :one
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
template_versions
|
||||
WHERE
|
||||
organization_id = $1
|
||||
AND "name" = $2;
|
||||
|
||||
-- name: GetTemplateVersionByID :one
|
||||
SELECT
|
||||
*
|
||||
|
||||
+69
-14
@@ -763,22 +763,50 @@ func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) {
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user))
|
||||
}
|
||||
|
||||
// @Summary Get template version by organization and name
|
||||
// @ID get-template-version-by-organization-and-name
|
||||
// @Summary Get template version by organization, template, and name
|
||||
// @ID get-template-version-by-organization-template-and-name
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Templates
|
||||
// @Param organization path string true "Organization ID" format(uuid)
|
||||
// @Param templatename path string true "Template name"
|
||||
// @Param templateversionname path string true "Template version name"
|
||||
// @Success 200 {object} codersdk.TemplateVersion
|
||||
// @Router /organizations/{organization}/templateversions/{templateversionname} [get]
|
||||
func (api *API) templateVersionByOrganizationAndName(rw http.ResponseWriter, r *http.Request) {
|
||||
// @Router /organizations/{organization}/templates/{templatename}/versions/{templateversionname} [get]
|
||||
func (api *API) templateVersionByOrganizationTemplateAndName(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
organization := httpmw.OrganizationParam(r)
|
||||
templateVersionName := chi.URLParam(r, "templateversionname")
|
||||
templateVersion, err := api.Database.GetTemplateVersionByOrganizationAndName(ctx, database.GetTemplateVersionByOrganizationAndNameParams{
|
||||
templateName := chi.URLParam(r, "templatename")
|
||||
|
||||
template, err := api.Database.GetTemplateByOrganizationAndName(ctx, database.GetTemplateByOrganizationAndNameParams{
|
||||
OrganizationID: organization.ID,
|
||||
Name: templateVersionName,
|
||||
Name: templateName,
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error fetching template.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if !api.Authorize(r, rbac.ActionRead, template) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
|
||||
templateVersionName := chi.URLParam(r, "templateversionname")
|
||||
templateVersion, err := api.Database.GetTemplateVersionByTemplateIDAndName(ctx, database.GetTemplateVersionByTemplateIDAndNameParams{
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: template.ID,
|
||||
Valid: true,
|
||||
},
|
||||
Name: templateVersionName,
|
||||
})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
|
||||
@@ -814,22 +842,49 @@ func (api *API) templateVersionByOrganizationAndName(rw http.ResponseWriter, r *
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user))
|
||||
}
|
||||
|
||||
// @Summary Get previous template version by organization and name
|
||||
// @ID get-previous-template-version-by-organization-and-name
|
||||
// @Summary Get previous template version by organization, template, and name
|
||||
// @ID get-previous-template-version-by-organization-template-and-name
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Templates
|
||||
// @Param organization path string true "Organization ID" format(uuid)
|
||||
// @Param templatename path string true "Template name"
|
||||
// @Param templateversionname path string true "Template version name"
|
||||
// @Success 200 {object} codersdk.TemplateVersion
|
||||
// @Router /organizations/{organization}/templateversions/{templateversionname}/previous [get]
|
||||
func (api *API) previousTemplateVersionByOrganizationAndName(rw http.ResponseWriter, r *http.Request) {
|
||||
// @Router /organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous [get]
|
||||
func (api *API) previousTemplateVersionByOrganizationTemplateAndName(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
organization := httpmw.OrganizationParam(r)
|
||||
templateVersionName := chi.URLParam(r, "templateversionname")
|
||||
templateVersion, err := api.Database.GetTemplateVersionByOrganizationAndName(ctx, database.GetTemplateVersionByOrganizationAndNameParams{
|
||||
templateName := chi.URLParam(r, "templatename")
|
||||
template, err := api.Database.GetTemplateByOrganizationAndName(ctx, database.GetTemplateByOrganizationAndNameParams{
|
||||
OrganizationID: organization.ID,
|
||||
Name: templateVersionName,
|
||||
Name: templateName,
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error fetching template.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if !api.Authorize(r, rbac.ActionRead, template) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
|
||||
templateVersionName := chi.URLParam(r, "templateversionname")
|
||||
templateVersion, err := api.Database.GetTemplateVersionByTemplateIDAndName(ctx, database.GetTemplateVersionByTemplateIDAndNameParams{
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: template.ID,
|
||||
Valid: true,
|
||||
},
|
||||
Name: templateVersionName,
|
||||
})
|
||||
if err != nil {
|
||||
if xerrors.Is(err, sql.ErrNoRows) {
|
||||
|
||||
@@ -992,19 +992,19 @@ func TestPaginatedTemplateVersions(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTemplateVersionByOrganizationAndName(t *testing.T) {
|
||||
func TestTemplateVersionByOrganizationTemplateAndName(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("NotFound", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
_, err := client.TemplateVersionByOrganizationAndName(ctx, user.OrganizationID, "nothing")
|
||||
_, err := client.TemplateVersionByOrganizationAndName(ctx, user.OrganizationID, template.Name, "nothing")
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
||||
@@ -1015,12 +1015,12 @@ func TestTemplateVersionByOrganizationAndName(t *testing.T) {
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
_, err := client.TemplateVersionByOrganizationAndName(ctx, user.OrganizationID, version.Name)
|
||||
_, err := client.TemplateVersionByOrganizationAndName(ctx, user.OrganizationID, template.Name, version.Name)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
@@ -1048,7 +1048,7 @@ func TestPreviousTemplateVersion(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
_, err := client.PreviousTemplateVersion(ctx, user.OrganizationID, templateBVersion1.Name)
|
||||
_, err := client.PreviousTemplateVersion(ctx, user.OrganizationID, templateB.Name, templateBVersion1.Name)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
||||
@@ -1075,7 +1075,7 @@ func TestPreviousTemplateVersion(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
result, err := client.PreviousTemplateVersion(ctx, user.OrganizationID, templateBVersion2.Name)
|
||||
result, err := client.PreviousTemplateVersion(ctx, user.OrganizationID, templateB.Name, templateBVersion2.Name)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, templateBVersion1.ID, result.ID)
|
||||
})
|
||||
|
||||
@@ -153,9 +153,9 @@ func (c *Client) CreateTemplateVersion(ctx context.Context, organizationID uuid.
|
||||
return templateVersion, json.NewDecoder(res.Body).Decode(&templateVersion)
|
||||
}
|
||||
|
||||
func (c *Client) TemplateVersionByOrganizationAndName(ctx context.Context, organizationID uuid.UUID, name string) (TemplateVersion, error) {
|
||||
func (c *Client) TemplateVersionByOrganizationAndName(ctx context.Context, organizationID uuid.UUID, templateName, versionName string) (TemplateVersion, error) {
|
||||
res, err := c.Request(ctx, http.MethodGet,
|
||||
fmt.Sprintf("/api/v2/organizations/%s/templateversions/%s", organizationID.String(), name),
|
||||
fmt.Sprintf("/api/v2/organizations/%s/templates/%s/versions/%s", organizationID.String(), templateName, versionName),
|
||||
nil,
|
||||
)
|
||||
|
||||
|
||||
@@ -221,8 +221,8 @@ func (c *Client) CancelTemplateVersionDryRun(ctx context.Context, version, job u
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) PreviousTemplateVersion(ctx context.Context, organization uuid.UUID, versionName string) (TemplateVersion, error) {
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/templateversions/%s/previous", organization, versionName), nil)
|
||||
func (c *Client) PreviousTemplateVersion(ctx context.Context, organization uuid.UUID, templateName, versionName string) (TemplateVersion, error) {
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/templates/%s/versions/%s/previous", organization, templateName, versionName), nil)
|
||||
if err != nil {
|
||||
return TemplateVersion{}, err
|
||||
}
|
||||
|
||||
+152
-150
@@ -375,6 +375,158 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat
|
||||
|
||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||
|
||||
## Get template version by organization, template, and name
|
||||
|
||||
### Code samples
|
||||
|
||||
```shell
|
||||
# Example request using curl
|
||||
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templates/{templatename}/versions/{templateversionname} \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Coder-Session-Token: API_KEY'
|
||||
```
|
||||
|
||||
`GET /organizations/{organization}/templates/{templatename}/versions/{templateversionname}`
|
||||
|
||||
### Parameters
|
||||
|
||||
| Name | In | Type | Required | Description |
|
||||
| --------------------- | ---- | ------------ | -------- | --------------------- |
|
||||
| `organization` | path | string(uuid) | true | Organization ID |
|
||||
| `templatename` | path | string | true | Template name |
|
||||
| `templateversionname` | path | string | true | Template version name |
|
||||
|
||||
### Example responses
|
||||
|
||||
> 200 Response
|
||||
|
||||
```json
|
||||
{
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"created_by": {
|
||||
"avatar_url": "http://example.com",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"email": "user@example.com",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"last_seen_at": "2019-08-24T14:15:22Z",
|
||||
"organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"],
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
"username": "string"
|
||||
},
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"job": {
|
||||
"canceled_at": "2019-08-24T14:15:22Z",
|
||||
"completed_at": "2019-08-24T14:15:22Z",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"error": "string",
|
||||
"file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"started_at": "2019-08-24T14:15:22Z",
|
||||
"status": "pending",
|
||||
"tags": {
|
||||
"property1": "string",
|
||||
"property2": "string"
|
||||
},
|
||||
"worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b"
|
||||
},
|
||||
"name": "string",
|
||||
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
|
||||
"readme": "string",
|
||||
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
|
||||
"updated_at": "2019-08-24T14:15:22Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Responses
|
||||
|
||||
| Status | Meaning | Description | Schema |
|
||||
| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------- |
|
||||
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) |
|
||||
|
||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||
|
||||
## Get previous template version by organization, template, and name
|
||||
|
||||
### Code samples
|
||||
|
||||
```shell
|
||||
# Example request using curl
|
||||
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Coder-Session-Token: API_KEY'
|
||||
```
|
||||
|
||||
`GET /organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous`
|
||||
|
||||
### Parameters
|
||||
|
||||
| Name | In | Type | Required | Description |
|
||||
| --------------------- | ---- | ------------ | -------- | --------------------- |
|
||||
| `organization` | path | string(uuid) | true | Organization ID |
|
||||
| `templatename` | path | string | true | Template name |
|
||||
| `templateversionname` | path | string | true | Template version name |
|
||||
|
||||
### Example responses
|
||||
|
||||
> 200 Response
|
||||
|
||||
```json
|
||||
{
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"created_by": {
|
||||
"avatar_url": "http://example.com",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"email": "user@example.com",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"last_seen_at": "2019-08-24T14:15:22Z",
|
||||
"organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"],
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
"username": "string"
|
||||
},
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"job": {
|
||||
"canceled_at": "2019-08-24T14:15:22Z",
|
||||
"completed_at": "2019-08-24T14:15:22Z",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"error": "string",
|
||||
"file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"started_at": "2019-08-24T14:15:22Z",
|
||||
"status": "pending",
|
||||
"tags": {
|
||||
"property1": "string",
|
||||
"property2": "string"
|
||||
},
|
||||
"worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b"
|
||||
},
|
||||
"name": "string",
|
||||
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
|
||||
"readme": "string",
|
||||
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
|
||||
"updated_at": "2019-08-24T14:15:22Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Responses
|
||||
|
||||
| Status | Meaning | Description | Schema |
|
||||
| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------- |
|
||||
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) |
|
||||
|
||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||
|
||||
## Create template version by organization
|
||||
|
||||
### Code samples
|
||||
@@ -474,156 +626,6 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa
|
||||
|
||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||
|
||||
## Get template version by organization and name
|
||||
|
||||
### Code samples
|
||||
|
||||
```shell
|
||||
# Example request using curl
|
||||
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templateversions/{templateversionname} \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Coder-Session-Token: API_KEY'
|
||||
```
|
||||
|
||||
`GET /organizations/{organization}/templateversions/{templateversionname}`
|
||||
|
||||
### Parameters
|
||||
|
||||
| Name | In | Type | Required | Description |
|
||||
| --------------------- | ---- | ------------ | -------- | --------------------- |
|
||||
| `organization` | path | string(uuid) | true | Organization ID |
|
||||
| `templateversionname` | path | string | true | Template version name |
|
||||
|
||||
### Example responses
|
||||
|
||||
> 200 Response
|
||||
|
||||
```json
|
||||
{
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"created_by": {
|
||||
"avatar_url": "http://example.com",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"email": "user@example.com",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"last_seen_at": "2019-08-24T14:15:22Z",
|
||||
"organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"],
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
"username": "string"
|
||||
},
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"job": {
|
||||
"canceled_at": "2019-08-24T14:15:22Z",
|
||||
"completed_at": "2019-08-24T14:15:22Z",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"error": "string",
|
||||
"file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"started_at": "2019-08-24T14:15:22Z",
|
||||
"status": "pending",
|
||||
"tags": {
|
||||
"property1": "string",
|
||||
"property2": "string"
|
||||
},
|
||||
"worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b"
|
||||
},
|
||||
"name": "string",
|
||||
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
|
||||
"readme": "string",
|
||||
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
|
||||
"updated_at": "2019-08-24T14:15:22Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Responses
|
||||
|
||||
| Status | Meaning | Description | Schema |
|
||||
| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------- |
|
||||
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) |
|
||||
|
||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||
|
||||
## Get previous template version by organization and name
|
||||
|
||||
### Code samples
|
||||
|
||||
```shell
|
||||
# Example request using curl
|
||||
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templateversions/{templateversionname}/previous \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Coder-Session-Token: API_KEY'
|
||||
```
|
||||
|
||||
`GET /organizations/{organization}/templateversions/{templateversionname}/previous`
|
||||
|
||||
### Parameters
|
||||
|
||||
| Name | In | Type | Required | Description |
|
||||
| --------------------- | ---- | ------------ | -------- | --------------------- |
|
||||
| `organization` | path | string(uuid) | true | Organization ID |
|
||||
| `templateversionname` | path | string | true | Template version name |
|
||||
|
||||
### Example responses
|
||||
|
||||
> 200 Response
|
||||
|
||||
```json
|
||||
{
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"created_by": {
|
||||
"avatar_url": "http://example.com",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"email": "user@example.com",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"last_seen_at": "2019-08-24T14:15:22Z",
|
||||
"organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"],
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
"username": "string"
|
||||
},
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"job": {
|
||||
"canceled_at": "2019-08-24T14:15:22Z",
|
||||
"completed_at": "2019-08-24T14:15:22Z",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"error": "string",
|
||||
"file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"started_at": "2019-08-24T14:15:22Z",
|
||||
"status": "pending",
|
||||
"tags": {
|
||||
"property1": "string",
|
||||
"property2": "string"
|
||||
},
|
||||
"worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b"
|
||||
},
|
||||
"name": "string",
|
||||
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
|
||||
"readme": "string",
|
||||
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
|
||||
"updated_at": "2019-08-24T14:15:22Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Responses
|
||||
|
||||
| Status | Meaning | Description | Schema |
|
||||
| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------- |
|
||||
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) |
|
||||
|
||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||
|
||||
## Get template metadata by ID
|
||||
|
||||
### Code samples
|
||||
|
||||
+4
-2
@@ -231,10 +231,11 @@ export const getTemplateVersions = async (
|
||||
|
||||
export const getTemplateVersionByName = async (
|
||||
organizationId: string,
|
||||
templateName: string,
|
||||
versionName: string,
|
||||
): Promise<TypesGen.TemplateVersion> => {
|
||||
const response = await axios.get<TypesGen.TemplateVersion>(
|
||||
`/api/v2/organizations/${organizationId}/templateversions/${versionName}`,
|
||||
`/api/v2/organizations/${organizationId}/templates/${templateName}/versions/${versionName}`,
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
@@ -245,11 +246,12 @@ export type GetPreviousTemplateVersionByNameResponse =
|
||||
|
||||
export const getPreviousTemplateVersionByName = async (
|
||||
organizationId: string,
|
||||
templateName: string,
|
||||
versionName: string,
|
||||
): Promise<GetPreviousTemplateVersionByNameResponse> => {
|
||||
try {
|
||||
const response = await axios.get<TypesGen.TemplateVersion>(
|
||||
`/api/v2/organizations/${organizationId}/templateversions/${versionName}/previous`,
|
||||
`/api/v2/organizations/${organizationId}/templates/${templateName}/versions/${versionName}/previous`,
|
||||
)
|
||||
return response.data
|
||||
} catch (error) {
|
||||
|
||||
@@ -18,7 +18,7 @@ export const TemplateVersionPage: FC = () => {
|
||||
const { version: versionName, template: templateName } = useParams() as Params
|
||||
const orgId = useOrganizationId()
|
||||
const [state] = useMachine(templateVersionMachine, {
|
||||
context: { versionName, orgId },
|
||||
context: { templateName, versionName, orgId },
|
||||
})
|
||||
const tab = useTab("file", "0")
|
||||
const { t } = useTranslation("templateVersionPage")
|
||||
|
||||
@@ -90,13 +90,13 @@ export const handlers = [
|
||||
},
|
||||
),
|
||||
rest.get(
|
||||
"api/v2/organizations/:organizationId/templateversions/:templateVersionName",
|
||||
"api/v2/organizations/:organizationId/templates/:templateName/versions/:templateVersionName",
|
||||
async (req, res, ctx) => {
|
||||
return res(ctx.status(200), ctx.json(M.MockTemplateVersion))
|
||||
},
|
||||
),
|
||||
rest.get(
|
||||
"api/v2/organizations/:organizationId/templateversions/:templateVersionName/previous",
|
||||
"api/v2/organizations/:organizationId/templates/:templateName/versions/:templateVersionName/previous",
|
||||
async (req, res, ctx) => {
|
||||
return res(ctx.status(200), ctx.json(M.MockTemplateVersion2))
|
||||
},
|
||||
|
||||
@@ -12,6 +12,7 @@ import { assign, createMachine } from "xstate"
|
||||
|
||||
export interface TemplateVersionMachineContext {
|
||||
orgId: string
|
||||
templateName: string
|
||||
versionName: string
|
||||
currentVersion?: TemplateVersion
|
||||
currentFiles?: TemplateVersionFiles
|
||||
@@ -94,10 +95,10 @@ export const templateVersionMachine = createMachine(
|
||||
}),
|
||||
},
|
||||
services: {
|
||||
loadVersions: async ({ orgId, versionName }) => {
|
||||
loadVersions: async ({ orgId, templateName, versionName }) => {
|
||||
const [currentVersion, previousVersion] = await Promise.all([
|
||||
getTemplateVersionByName(orgId, versionName),
|
||||
getPreviousTemplateVersionByName(orgId, versionName),
|
||||
getTemplateVersionByName(orgId, templateName, versionName),
|
||||
getPreviousTemplateVersionByName(orgId, templateName, versionName),
|
||||
])
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user